Add exception callbacks to EglThread
This allows EglRenderer to preserve existing behavior of not sending any more tasks to the render thread after an GL exception has been thrown. Bug: b/225229697 Change-Id: I09e7cc48bf139aab4c9e147c2b24972ccd401672 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/311548 Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Commit-Queue: Linus Nilsson <lnilsson@webrtc.org> Cr-Commit-Position: refs/heads/main@{#40419}
This commit is contained in:
parent
6a4f409241
commit
4200233adc
@ -12,8 +12,12 @@ package org.webrtc;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import androidx.annotation.GuardedBy;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.webrtc.EglBase.EglConnection;
|
||||
|
||||
/** EGL graphics thread that allows multiple clients to share the same underlying EGLContext. */
|
||||
@ -31,7 +35,8 @@ public class EglThread {
|
||||
@Nullable final EglBase.Context sharedContext, final int[] configAttributes) {
|
||||
final HandlerThread renderThread = new HandlerThread("EglThread");
|
||||
renderThread.start();
|
||||
Handler handler = new Handler(renderThread.getLooper());
|
||||
HandlerWithExceptionCallbacks handler =
|
||||
new HandlerWithExceptionCallbacks(renderThread.getLooper());
|
||||
|
||||
// Not creating the EGLContext on the thread it will be used on seems to cause issues with
|
||||
// creating window surfaces on certain devices. So keep the same legacy behavior as EglRenderer
|
||||
@ -51,12 +56,51 @@ public class EglThread {
|
||||
releaseMonitor != null ? releaseMonitor : eglThread -> true, handler, eglConnection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler that triggers callbacks when an uncaught exception happens when handling a message.
|
||||
*/
|
||||
private static class HandlerWithExceptionCallbacks extends Handler {
|
||||
private final Object callbackLock = new Object();
|
||||
@GuardedBy("callbackLock") private final List<Runnable> exceptionCallbacks = new ArrayList<>();
|
||||
|
||||
public HandlerWithExceptionCallbacks(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchMessage(Message msg) {
|
||||
try {
|
||||
super.dispatchMessage(msg);
|
||||
} catch (Exception e) {
|
||||
Logging.e("EglThread", "Exception on EglThread", e);
|
||||
synchronized (callbackLock) {
|
||||
for (Runnable callback : exceptionCallbacks) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public void addExceptionCallback(Runnable callback) {
|
||||
synchronized (callbackLock) {
|
||||
exceptionCallbacks.add(callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeExceptionCallback(Runnable callback) {
|
||||
synchronized (callbackLock) {
|
||||
exceptionCallbacks.remove(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final ReleaseMonitor releaseMonitor;
|
||||
private final Handler handler;
|
||||
private final HandlerWithExceptionCallbacks handler;
|
||||
private final EglConnection eglConnection;
|
||||
|
||||
@VisibleForTesting
|
||||
EglThread(ReleaseMonitor releaseMonitor, Handler handler, EglConnection eglConnection) {
|
||||
private EglThread(ReleaseMonitor releaseMonitor, HandlerWithExceptionCallbacks handler,
|
||||
EglConnection eglConnection) {
|
||||
this.releaseMonitor = releaseMonitor;
|
||||
this.handler = handler;
|
||||
this.eglConnection = eglConnection;
|
||||
@ -88,4 +132,18 @@ public class EglThread {
|
||||
public Handler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a callback that will be called on the EGL thread if there is an exception on the thread.
|
||||
*/
|
||||
public void addExceptionCallback(Runnable callback) {
|
||||
handler.addExceptionCallback(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a previously added exception callback.
|
||||
*/
|
||||
public void removeExceptionCallback(Runnable callback) {
|
||||
handler.removeExceptionCallback(callback);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user