mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-12-17 05:24:19 +01:00
Extract function to execute code on a handler
Extract function to synchronously execute code on a handler, waiting for the execution to complete.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package com.genymobile.scrcpy.opengl;
|
package com.genymobile.scrcpy.opengl;
|
||||||
|
|
||||||
import com.genymobile.scrcpy.device.Size;
|
import com.genymobile.scrcpy.device.Size;
|
||||||
|
import com.genymobile.scrcpy.util.Threads;
|
||||||
|
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.opengl.EGL14;
|
import android.opengl.EGL14;
|
||||||
@@ -15,6 +16,7 @@ import android.os.Handler;
|
|||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
public final class OpenGLRunner {
|
public final class OpenGLRunner {
|
||||||
@@ -80,31 +82,17 @@ public final class OpenGLRunner {
|
|||||||
public Surface start(Size inputSize, Size outputSize, Surface outputSurface) throws OpenGLException {
|
public Surface start(Size inputSize, Size outputSize, Surface outputSurface) throws OpenGLException {
|
||||||
initOnce();
|
initOnce();
|
||||||
|
|
||||||
// Simulate CompletableFuture, but working for all Android versions
|
|
||||||
final Semaphore sem = new Semaphore(0);
|
|
||||||
Throwable[] throwableRef = new Throwable[1];
|
|
||||||
|
|
||||||
// The whole OpenGL execution must be performed on a Handler, so that SurfaceTexture.setOnFrameAvailableListener() works correctly.
|
// The whole OpenGL execution must be performed on a Handler, so that SurfaceTexture.setOnFrameAvailableListener() works correctly.
|
||||||
// See <https://github.com/Genymobile/scrcpy/issues/5444>
|
// See <https://github.com/Genymobile/scrcpy/issues/5444>
|
||||||
handler.post(() -> {
|
|
||||||
try {
|
|
||||||
run(inputSize, outputSize, outputSurface);
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
throwableRef[0] = throwable;
|
|
||||||
} finally {
|
|
||||||
sem.release();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sem.acquire();
|
Threads.executeSynchronouslyOn(handler, new Callable<Void>() {
|
||||||
} catch (InterruptedException e) {
|
@Override
|
||||||
// Behave as if this method call was synchronous
|
public Void call() throws Exception {
|
||||||
Thread.currentThread().interrupt();
|
run(inputSize, outputSize, outputSurface);
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
Throwable throwable = throwableRef[0];
|
});
|
||||||
if (throwable != null) {
|
} catch (Throwable throwable) {
|
||||||
if (throwable instanceof OpenGLException) {
|
if (throwable instanceof OpenGLException) {
|
||||||
throw (OpenGLException) throwable;
|
throw (OpenGLException) throwable;
|
||||||
}
|
}
|
||||||
|
|||||||
43
server/src/main/java/com/genymobile/scrcpy/util/Threads.java
Normal file
43
server/src/main/java/com/genymobile/scrcpy/util/Threads.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package com.genymobile.scrcpy.util;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
|
public final class Threads {
|
||||||
|
private Threads() {
|
||||||
|
// not instantiable
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T executeSynchronouslyOn(Handler handler, Callable<T> callable) throws Throwable {
|
||||||
|
// Simulate CompletableFuture, but working for all Android versions
|
||||||
|
final Semaphore sem = new Semaphore(0);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
T[] resultRef = (T[]) new Object[1];
|
||||||
|
Throwable[] throwableRef = new Throwable[1];
|
||||||
|
|
||||||
|
handler.post(() -> {
|
||||||
|
try {
|
||||||
|
resultRef[0] = callable.call();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
throwableRef[0] = throwable;
|
||||||
|
} finally {
|
||||||
|
sem.release();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
sem.acquire();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// Behave as if this method call was synchronous
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (throwableRef[0] != null) {
|
||||||
|
throw throwableRef[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultRef[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user