mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 11:03:01 +00:00
Disable performance optimizations when in multi-window
This commit is contained in:
parent
4deb881ec8
commit
912925ef2c
@ -29,6 +29,7 @@ import com.limelight.utils.SpinnerDialog;
|
|||||||
import com.limelight.utils.UiHelper;
|
import com.limelight.utils.UiHelper;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.PictureInPictureParams;
|
import android.app.PictureInPictureParams;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
@ -517,16 +518,27 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@TargetApi(Build.VERSION_CODES.N)
|
||||||
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
|
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
|
||||||
super.onMultiWindowModeChanged(isInMultiWindowMode);
|
super.onMultiWindowModeChanged(isInMultiWindowMode);
|
||||||
|
|
||||||
// In multi-window, we don't want to use the full-screen layout
|
// In multi-window, we don't want to use the full-screen layout
|
||||||
// flag. It will cause us to collide with the system UI.
|
// flag. It will cause us to collide with the system UI.
|
||||||
|
// This function will also be called for PiP so we can cover
|
||||||
|
// that case here too.
|
||||||
if (isInMultiWindowMode) {
|
if (isInMultiWindowMode) {
|
||||||
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
|
// Disable performance optimizations for foreground
|
||||||
|
getWindow().setSustainedPerformanceMode(false);
|
||||||
|
decoderRenderer.notifyVideoBackground();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
|
||||||
|
// Enable performance optimizations for foreground
|
||||||
|
getWindow().setSustainedPerformanceMode(true);
|
||||||
|
decoderRenderer.notifyVideoForeground();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Correct the system UI visibility flags
|
// Correct the system UI visibility flags
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.limelight.binding.video;
|
package com.limelight.binding.video;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.jcodec.codecs.h264.H264Utils;
|
import org.jcodec.codecs.h264.H264Utils;
|
||||||
@ -123,8 +124,8 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
this.crashListener = crashListener;
|
this.crashListener = crashListener;
|
||||||
this.consecutiveCrashCount = consecutiveCrashCount;
|
this.consecutiveCrashCount = consecutiveCrashCount;
|
||||||
|
|
||||||
// Disable spinner threads in battery saver mode
|
// Disable spinner threads in battery saver mode or 4K
|
||||||
if (prefs.batterySaver) {
|
if (prefs.batterySaver || prefs.height >= 2160) {
|
||||||
spinnerThreads = new Thread[0];
|
spinnerThreads = new Thread[0];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -193,6 +194,17 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void notifyVideoForeground() {
|
||||||
|
startSpinnerThreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyVideoBackground() {
|
||||||
|
// Signal the spinner threads to stop but
|
||||||
|
// don't wait for them to terminate to avoid
|
||||||
|
// delaying the state transition
|
||||||
|
signalSpinnerStop();
|
||||||
|
}
|
||||||
|
|
||||||
public int getActiveVideoFormat() {
|
public int getActiveVideoFormat() {
|
||||||
return this.videoFormat;
|
return this.videoFormat;
|
||||||
}
|
}
|
||||||
@ -424,26 +436,70 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
rendererThread.start();
|
rendererThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startSpinnerThread(final int i) {
|
||||||
|
spinnerThreads[i] = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// This thread exists to keep the CPU at a higher DVFS state on devices
|
||||||
|
// where the governor scales clock speed sporadically, causing dropped frames.
|
||||||
|
//
|
||||||
|
// Run until we notice our thread has been removed from the spinner threads
|
||||||
|
// array. Even if we don't notice immediately, we'll notice soon enough.
|
||||||
|
// This will also ensure we terminate even if someone has restarted spinning
|
||||||
|
// before we realized we should stop.
|
||||||
|
while (this == spinnerThreads[i]) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(0, 1);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
spinnerThreads[i].setName("Spinner-"+i);
|
||||||
|
spinnerThreads[i].setPriority(Thread.MIN_PRIORITY);
|
||||||
|
spinnerThreads[i].start();
|
||||||
|
}
|
||||||
|
|
||||||
private void startSpinnerThreads() {
|
private void startSpinnerThreads() {
|
||||||
LimeLog.info("Using "+spinnerThreads.length+" spinner threads");
|
LimeLog.info("Using "+spinnerThreads.length+" spinner threads");
|
||||||
for (int i = 0; i < spinnerThreads.length; i++) {
|
for (int i = 0; i < spinnerThreads.length; i++) {
|
||||||
spinnerThreads[i] = new Thread() {
|
if (spinnerThreads[i] != null) {
|
||||||
@Override
|
continue;
|
||||||
public void run() {
|
}
|
||||||
// This thread exists to keep the CPU at a higher DVFS state on devices
|
|
||||||
// where the governor scales clock speed sporadically, causing dropped frames.
|
startSpinnerThread(i);
|
||||||
while (!stopping) {
|
}
|
||||||
try {
|
}
|
||||||
Thread.sleep(0, 1);
|
|
||||||
} catch (InterruptedException e) {
|
private Thread[] signalSpinnerStop() {
|
||||||
break;
|
// Capture current running threads
|
||||||
}
|
Thread[] runningThreads = Arrays.copyOf(spinnerThreads, spinnerThreads.length);
|
||||||
}
|
|
||||||
}
|
// Clear the spinner threads to signal their termination
|
||||||
};
|
for (int i = 0; i < spinnerThreads.length; i++) {
|
||||||
spinnerThreads[i].setName("Spinner-"+i);
|
spinnerThreads[i] = null;
|
||||||
spinnerThreads[i].setPriority(Thread.MIN_PRIORITY);
|
}
|
||||||
spinnerThreads[i].start();
|
|
||||||
|
// Interrupt the threads
|
||||||
|
for (int i = 0; i < runningThreads.length; i++) {
|
||||||
|
if (runningThreads[i] != null) {
|
||||||
|
runningThreads[i].interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return runningThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopSpinnerThreads() {
|
||||||
|
// Signal and wait for the threads to stop
|
||||||
|
Thread[] runningThreads = signalSpinnerStop();
|
||||||
|
for (int i = 0; i < runningThreads.length; i++) {
|
||||||
|
if (runningThreads[i] != null) {
|
||||||
|
try {
|
||||||
|
runningThreads[i].join();
|
||||||
|
} catch (InterruptedException ignored) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,14 +573,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Halt the spinner threads
|
// Halt the spinner threads
|
||||||
for (Thread t : spinnerThreads) {
|
stopSpinnerThreads();
|
||||||
t.interrupt();
|
|
||||||
}
|
|
||||||
for (Thread t : spinnerThreads) {
|
|
||||||
try {
|
|
||||||
t.join();
|
|
||||||
} catch (InterruptedException ignored) { }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user