Batch ACTION_MOVE events to vsync boundries when resizing task
- Created helper class BatchedInputEventReceiver for batching ACTION_MOVE events to vsync boundries. - Switched TaskPositioner to use new helper class for input events so we reduce the number of input events we process per vsync. Bug: 24375616 Change-Id: I4ee27949b956784fb89d8f190497e4765522c9d3
This commit is contained in:
82
core/java/android/view/BatchedInputEventReceiver.java
Normal file
82
core/java/android/view/BatchedInputEventReceiver.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.os.Looper;
|
||||
|
||||
/**
|
||||
* Similar to {@link InputEventReceiver}, but batches events to vsync boundaries when possible.
|
||||
* @hide
|
||||
*/
|
||||
public class BatchedInputEventReceiver extends InputEventReceiver {
|
||||
Choreographer mChoreographer;
|
||||
private boolean mBatchedInputScheduled;
|
||||
|
||||
public BatchedInputEventReceiver(
|
||||
InputChannel inputChannel, Looper looper, Choreographer choreographer) {
|
||||
super(inputChannel, looper);
|
||||
mChoreographer = choreographer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBatchedInputEventPending() {
|
||||
scheduleBatchedInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
unscheduleBatchedInput();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void doConsumeBatchedInput(long frameTimeNanos) {
|
||||
if (mBatchedInputScheduled) {
|
||||
mBatchedInputScheduled = false;
|
||||
if (consumeBatchedInputEvents(frameTimeNanos) && frameTimeNanos != -1) {
|
||||
// If we consumed a batch here, we want to go ahead and schedule the
|
||||
// consumption of batched input events on the next frame. Otherwise, we would
|
||||
// wait until we have more input events pending and might get starved by other
|
||||
// things occurring in the process. If the frame time is -1, however, then
|
||||
// we're in a non-batching mode, so there's no need to schedule this.
|
||||
scheduleBatchedInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleBatchedInput() {
|
||||
if (!mBatchedInputScheduled) {
|
||||
mBatchedInputScheduled = true;
|
||||
mChoreographer.postCallback(Choreographer.CALLBACK_INPUT, mBatchedInputRunnable, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void unscheduleBatchedInput() {
|
||||
if (mBatchedInputScheduled) {
|
||||
mBatchedInputScheduled = false;
|
||||
mChoreographer.removeCallbacks(
|
||||
Choreographer.CALLBACK_INPUT, mBatchedInputRunnable, null);
|
||||
}
|
||||
}
|
||||
|
||||
private final class BatchedInputRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
doConsumeBatchedInput(mChoreographer.getFrameTimeNanos());
|
||||
}
|
||||
}
|
||||
private final BatchedInputRunnable mBatchedInputRunnable = new BatchedInputRunnable();
|
||||
}
|
||||
@@ -35,12 +35,13 @@ import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Slog;
|
||||
import android.view.Choreographer;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.InputChannel;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputEvent;
|
||||
import android.view.InputEventReceiver;
|
||||
import android.view.BatchedInputEventReceiver;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowManager;
|
||||
@@ -102,9 +103,10 @@ class TaskPositioner implements DimLayer.DimLayerUser {
|
||||
InputApplicationHandle mDragApplicationHandle;
|
||||
InputWindowHandle mDragWindowHandle;
|
||||
|
||||
private final class WindowPositionerEventReceiver extends InputEventReceiver {
|
||||
public WindowPositionerEventReceiver(InputChannel inputChannel, Looper looper) {
|
||||
super(inputChannel, looper);
|
||||
private final class WindowPositionerEventReceiver extends BatchedInputEventReceiver {
|
||||
public WindowPositionerEventReceiver(
|
||||
InputChannel inputChannel, Looper looper, Choreographer choreographer) {
|
||||
super(inputChannel, looper, choreographer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -214,8 +216,8 @@ class TaskPositioner implements DimLayer.DimLayerUser {
|
||||
mClientChannel = channels[1];
|
||||
mService.mInputManager.registerInputChannel(mServerChannel, null);
|
||||
|
||||
mInputEventReceiver = new WindowPositionerEventReceiver(mClientChannel,
|
||||
mService.mH.getLooper());
|
||||
mInputEventReceiver = new WindowPositionerEventReceiver(
|
||||
mClientChannel, mService.mH.getLooper(), mService.mChoreographer);
|
||||
|
||||
mDragApplicationHandle = new InputApplicationHandle(null);
|
||||
mDragApplicationHandle.name = TAG;
|
||||
|
||||
Reference in New Issue
Block a user