Skip to content

Commit

Permalink
Disable performance optimizations when in multi-window
Browse files Browse the repository at this point in the history
  • Loading branch information
cgutman committed Nov 19, 2017
1 parent 4deb881 commit 912925e
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 27 deletions.
12 changes: 12 additions & 0 deletions app/src/main/java/com/limelight/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.limelight.utils.UiHelper;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.PictureInPictureParams;
import android.app.Service;
Expand Down Expand Up @@ -517,16 +518,27 @@ private void hideSystemUi(int delay) {
}

@Override
@TargetApi(Build.VERSION_CODES.N)
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
super.onMultiWindowModeChanged(isInMultiWindowMode);

// In multi-window, we don't want to use the full-screen layout
// 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) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

// Disable performance optimizations for foreground
getWindow().setSustainedPerformanceMode(false);
decoderRenderer.notifyVideoBackground();
}
else {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

// Enable performance optimizations for foreground
getWindow().setSustainedPerformanceMode(true);
decoderRenderer.notifyVideoForeground();
}

// Correct the system UI visibility flags
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.limelight.binding.video;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Locale;

import org.jcodec.codecs.h264.H264Utils;
Expand Down Expand Up @@ -123,8 +124,8 @@ public MediaCodecDecoderRenderer(PreferenceConfiguration prefs,
this.crashListener = crashListener;
this.consecutiveCrashCount = consecutiveCrashCount;

// Disable spinner threads in battery saver mode
if (prefs.batterySaver) {
// Disable spinner threads in battery saver mode or 4K
if (prefs.batterySaver || prefs.height >= 2160) {
spinnerThreads = new Thread[0];
}
else {
Expand Down Expand Up @@ -193,6 +194,17 @@ public boolean isHevcMain10Hdr10Supported() {
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() {
return this.videoFormat;
}
Expand Down Expand Up @@ -424,26 +436,70 @@ public void run() {
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() {
LimeLog.info("Using "+spinnerThreads.length+" spinner threads");
for (int i = 0; i < spinnerThreads.length; 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.
while (!stopping) {
try {
Thread.sleep(0, 1);
} catch (InterruptedException e) {
break;
}
}
}
};
spinnerThreads[i].setName("Spinner-"+i);
spinnerThreads[i].setPriority(Thread.MIN_PRIORITY);
spinnerThreads[i].start();
if (spinnerThreads[i] != null) {
continue;
}

startSpinnerThread(i);
}
}

private Thread[] signalSpinnerStop() {
// 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] = null;
}

// 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) { }
}
}
}

Expand Down Expand Up @@ -517,14 +573,7 @@ public void stop() {
}

// Halt the spinner threads
for (Thread t : spinnerThreads) {
t.interrupt();
}
for (Thread t : spinnerThreads) {
try {
t.join();
} catch (InterruptedException ignored) { }
}
stopSpinnerThreads();
}

@Override
Expand Down

0 comments on commit 912925e

Please sign in to comment.