diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java index 922da7b0..9e3aa4eb 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera1Engine.java @@ -625,7 +625,7 @@ public class Camera1Engine extends CameraBaseEngine implements mZoomValue = zoom; // Zoom requests can be high frequency (e.g. linked to touch events), so // we remove the task before scheduling to avoid stack overflows in orchestrator. - getOrchestrator().remove("zoom"); + getOrchestrator().trim("zoom", ALLOWED_ZOOM_OPS); mZoomTask = getOrchestrator().scheduleStateful("zoom", CameraState.ENGINE, new Runnable() { @@ -660,7 +660,7 @@ public class Camera1Engine extends CameraBaseEngine implements mExposureCorrectionValue = EVvalue; // EV requests can be high frequency (e.g. linked to touch events), so // we remove the task before scheduling to avoid stack overflows in orchestrator. - getOrchestrator().remove("exposure correction"); + getOrchestrator().trim("exposure correction", ALLOWED_EV_OPS); mExposureCorrectionTask = getOrchestrator().scheduleStateful( "exposure correction", CameraState.ENGINE, diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java index 2fa7f385..3e07dbc8 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java @@ -1248,7 +1248,7 @@ public class Camera2Engine extends CameraBaseEngine implements mZoomValue = zoom; // Zoom requests can be high frequency (e.g. linked to touch events), so // we remove the task before scheduling to avoid stack overflows in orchestrator. - getOrchestrator().remove("zoom"); + getOrchestrator().trim("zoom", ALLOWED_ZOOM_OPS); mZoomTask = getOrchestrator().scheduleStateful( "zoom", CameraState.ENGINE, @@ -1307,7 +1307,7 @@ public class Camera2Engine extends CameraBaseEngine implements mExposureCorrectionValue = EVvalue; // EV requests can be high frequency (e.g. linked to touch events), so // we remove the task before scheduling to avoid stack overflows in orchestrator. - getOrchestrator().remove("exposure correction"); + getOrchestrator().trim("exposure correction", ALLOWED_EV_OPS); mExposureCorrectionTask = getOrchestrator().scheduleStateful( "exposure correction", CameraState.ENGINE, diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java index a751f4b0..b1f4caae 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/CameraBaseEngine.java @@ -50,6 +50,9 @@ import java.util.List; */ public abstract class CameraBaseEngine extends CameraEngine { + protected final static int ALLOWED_ZOOM_OPS = 10; + protected final static int ALLOWED_EV_OPS = 10; + @SuppressWarnings("WeakerAccess") protected CameraPreview mPreview; @SuppressWarnings("WeakerAccess") protected CameraOptions mCameraOptions; @SuppressWarnings("WeakerAccess") protected PictureRecorder mPictureRecorder; diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/orchestrator/CameraOrchestrator.java b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/orchestrator/CameraOrchestrator.java index d703eabf..60213356 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/engine/orchestrator/CameraOrchestrator.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/engine/orchestrator/CameraOrchestrator.java @@ -150,15 +150,28 @@ public class CameraOrchestrator { } public void remove(@NonNull String name) { + trim(name, 0); + } + + public void trim(@NonNull String name, int allowed) { synchronized (mLock) { - if (mDelayedJobs.get(name) != null) { + Token token = new Token(name, Tasks.forResult(null)); + int scheduled = 0; + for (Token job : mJobs) { + if (job == token) scheduled++; + } + boolean delayed = mDelayedJobs.containsKey(name); + if (delayed) scheduled++; + int existing = Math.max(scheduled - allowed, 0); + while (existing > 0 && mJobs.removeLastOccurrence(token)) { + existing--; + } + if (existing > 0 && delayed) { //noinspection ConstantConditions mCallback.getJobWorker(name).remove(mDelayedJobs.get(name)); mDelayedJobs.remove(name); + existing--; } - Token token = new Token(name, Tasks.forResult(null)); - //noinspection StatementWithEmptyBody - while (mJobs.remove(token)) { /* do nothing */ } ensureToken(); } }