Merge "Boost android.anim and wm lock sections to -10 during transition" into oc-dev
This commit is contained in:
@@ -16,14 +16,16 @@
|
|||||||
|
|
||||||
package com.android.server;
|
package com.android.server;
|
||||||
|
|
||||||
import android.os.Process;
|
import static android.os.Process.getThreadPriority;
|
||||||
|
import static android.os.Process.myTid;
|
||||||
|
import static android.os.Process.setThreadPriority;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to boost threads in sections where important locks are held.
|
* Utility class to boost threads in sections where important locks are held.
|
||||||
*/
|
*/
|
||||||
public class ThreadPriorityBooster {
|
public class ThreadPriorityBooster {
|
||||||
|
|
||||||
private final int mBoostToPriority;
|
private volatile int mBoostToPriority;
|
||||||
private final int mLockGuardIndex;
|
private final int mLockGuardIndex;
|
||||||
|
|
||||||
private final ThreadLocal<PriorityState> mThreadState = new ThreadLocal<PriorityState>() {
|
private final ThreadLocal<PriorityState> mThreadState = new ThreadLocal<PriorityState>() {
|
||||||
@@ -38,12 +40,12 @@ public class ThreadPriorityBooster {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void boost() {
|
public void boost() {
|
||||||
final int tid = Process.myTid();
|
final int tid = myTid();
|
||||||
final int prevPriority = Process.getThreadPriority(tid);
|
final int prevPriority = getThreadPriority(tid);
|
||||||
PriorityState state = mThreadState.get();
|
final PriorityState state = mThreadState.get();
|
||||||
state.prevPriority = prevPriority;
|
state.prevPriority = prevPriority;
|
||||||
if (state.regionCounter == 0 && prevPriority > mBoostToPriority) {
|
if (state.regionCounter == 0 && prevPriority > mBoostToPriority) {
|
||||||
Process.setThreadPriority(tid, mBoostToPriority);
|
setThreadPriority(tid, mBoostToPriority);
|
||||||
}
|
}
|
||||||
state.regionCounter++;
|
state.regionCounter++;
|
||||||
if (LockGuard.ENABLED) {
|
if (LockGuard.ENABLED) {
|
||||||
@@ -52,10 +54,28 @@ public class ThreadPriorityBooster {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
PriorityState state = mThreadState.get();
|
final PriorityState state = mThreadState.get();
|
||||||
state.regionCounter--;
|
state.regionCounter--;
|
||||||
if (state.regionCounter == 0 && state.prevPriority > mBoostToPriority) {
|
final int currentPriority = getThreadPriority(myTid());
|
||||||
Process.setThreadPriority(Process.myTid(), state.prevPriority);
|
if (state.regionCounter == 0 && state.prevPriority != currentPriority) {
|
||||||
|
setThreadPriority(myTid(), state.prevPriority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the priority we boost the threads to, and updates the current thread's priority if
|
||||||
|
* necessary.
|
||||||
|
*/
|
||||||
|
protected void setBoostToPriority(int priority) {
|
||||||
|
|
||||||
|
// We don't care about the other threads here, as long as they see the update of this
|
||||||
|
// variable immediately.
|
||||||
|
mBoostToPriority = priority;
|
||||||
|
final PriorityState state = mThreadState.get();
|
||||||
|
final int tid = myTid();
|
||||||
|
final int prevPriority = getThreadPriority(tid);
|
||||||
|
if (state.regionCounter != 0 && prevPriority != priority) {
|
||||||
|
setThreadPriority(tid, priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -453,6 +453,11 @@ import libcore.util.EmptyArray;
|
|||||||
public class ActivityManagerService extends IActivityManager.Stub
|
public class ActivityManagerService extends IActivityManager.Stub
|
||||||
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
|
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Priority we boost main thread and RT of top app to.
|
||||||
|
*/
|
||||||
|
public static final int TOP_APP_PRIORITY_BOOST = -10;
|
||||||
|
|
||||||
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
|
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
|
||||||
private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
|
private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
|
||||||
private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
|
private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
|
||||||
@@ -13426,7 +13431,7 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|||||||
setThreadScheduler(proc.renderThreadTid,
|
setThreadScheduler(proc.renderThreadTid,
|
||||||
SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
|
SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
|
||||||
} else {
|
} else {
|
||||||
setThreadPriority(proc.renderThreadTid, -10);
|
setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -21886,10 +21891,11 @@ public class ActivityManagerService extends IActivityManager.Stub
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Boost priority for top app UI and render threads
|
// Boost priority for top app UI and render threads
|
||||||
setThreadPriority(app.pid, -10);
|
setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
|
||||||
if (app.renderThreadTid != 0) {
|
if (app.renderThreadTid != 0) {
|
||||||
try {
|
try {
|
||||||
setThreadPriority(app.renderThreadTid, -10);
|
setThreadPriority(app.renderThreadTid,
|
||||||
|
TOP_APP_PRIORITY_BOOST);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// thread died, ignore
|
// thread died, ignore
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,6 +313,7 @@ public class AppTransition implements Dump {
|
|||||||
mNextAppTransition = transit;
|
mNextAppTransition = transit;
|
||||||
mNextAppTransitionFlags |= flags;
|
mNextAppTransitionFlags |= flags;
|
||||||
setLastAppTransition(TRANSIT_UNSET, null, null);
|
setLastAppTransition(TRANSIT_UNSET, null, null);
|
||||||
|
updateBooster();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLastAppTransition(int transit, AppWindowToken openingApp, AppWindowToken closingApp) {
|
void setLastAppTransition(int transit, AppWindowToken openingApp, AppWindowToken closingApp) {
|
||||||
@@ -327,7 +328,7 @@ public class AppTransition implements Dump {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setReady() {
|
void setReady() {
|
||||||
mAppTransitionState = APP_STATE_READY;
|
setAppTransitionState(APP_STATE_READY);
|
||||||
fetchAppTransitionSpecsFromFuture();
|
fetchAppTransitionSpecsFromFuture();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +337,7 @@ public class AppTransition implements Dump {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setIdle() {
|
void setIdle() {
|
||||||
mAppTransitionState = APP_STATE_IDLE;
|
setAppTransitionState(APP_STATE_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isTimeout() {
|
boolean isTimeout() {
|
||||||
@@ -344,7 +345,7 @@ public class AppTransition implements Dump {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setTimeout() {
|
void setTimeout() {
|
||||||
mAppTransitionState = APP_STATE_TIMEOUT;
|
setAppTransitionState(APP_STATE_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicBuffer getAppTransitionThumbnailHeader(int taskId) {
|
GraphicBuffer getAppTransitionThumbnailHeader(int taskId) {
|
||||||
@@ -386,7 +387,7 @@ public class AppTransition implements Dump {
|
|||||||
|
|
||||||
private boolean prepare() {
|
private boolean prepare() {
|
||||||
if (!isRunning()) {
|
if (!isRunning()) {
|
||||||
mAppTransitionState = APP_STATE_IDLE;
|
setAppTransitionState(APP_STATE_IDLE);
|
||||||
notifyAppTransitionPendingLocked();
|
notifyAppTransitionPendingLocked();
|
||||||
mLastHadClipReveal = false;
|
mLastHadClipReveal = false;
|
||||||
mLastClipRevealMaxTranslation = 0;
|
mLastClipRevealMaxTranslation = 0;
|
||||||
@@ -405,7 +406,7 @@ public class AppTransition implements Dump {
|
|||||||
ArraySet<AppWindowToken> closingApps) {
|
ArraySet<AppWindowToken> closingApps) {
|
||||||
mNextAppTransition = TRANSIT_UNSET;
|
mNextAppTransition = TRANSIT_UNSET;
|
||||||
mNextAppTransitionFlags = 0;
|
mNextAppTransitionFlags = 0;
|
||||||
mAppTransitionState = APP_STATE_RUNNING;
|
setAppTransitionState(APP_STATE_RUNNING);
|
||||||
int redoLayout = notifyAppTransitionStartingLocked(transit,
|
int redoLayout = notifyAppTransitionStartingLocked(transit,
|
||||||
topOpeningAppAnimator != null ? topOpeningAppAnimator.mAppToken.token : null,
|
topOpeningAppAnimator != null ? topOpeningAppAnimator.mAppToken.token : null,
|
||||||
topClosingAppAnimator != null ? topClosingAppAnimator.mAppToken.token : null,
|
topClosingAppAnimator != null ? topClosingAppAnimator.mAppToken.token : null,
|
||||||
@@ -450,6 +451,22 @@ public class AppTransition implements Dump {
|
|||||||
notifyAppTransitionCancelledLocked(transit);
|
notifyAppTransitionCancelledLocked(transit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setAppTransitionState(int state) {
|
||||||
|
mAppTransitionState = state;
|
||||||
|
updateBooster();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates whether we currently boost wm locked sections and the animation thread. We want to
|
||||||
|
* boost the priorities to a more important value whenever an app transition is going to happen
|
||||||
|
* soon or an app transition is running.
|
||||||
|
*/
|
||||||
|
private void updateBooster() {
|
||||||
|
WindowManagerService.sThreadPriorityBooster.setAppTransitionRunning(
|
||||||
|
mNextAppTransition != TRANSIT_UNSET || mAppTransitionState == APP_STATE_READY
|
||||||
|
|| mAppTransitionState == APP_STATE_RUNNING);
|
||||||
|
}
|
||||||
|
|
||||||
void registerListenerLocked(AppTransitionListener listener) {
|
void registerListenerLocked(AppTransitionListener listener) {
|
||||||
mListeners.add(listener);
|
mListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -870,8 +870,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
// since they won't be notified through the app window animator.
|
// since they won't be notified through the app window animator.
|
||||||
final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
|
final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
|
||||||
|
|
||||||
private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
|
static WindowManagerThreadPriorityBooster sThreadPriorityBooster =
|
||||||
THREAD_PRIORITY_DISPLAY, INDEX_WINDOW);
|
new WindowManagerThreadPriorityBooster();
|
||||||
|
|
||||||
static void boostPriorityForLockedSection() {
|
static void boostPriorityForLockedSection() {
|
||||||
sThreadPriorityBooster.boost();
|
sThreadPriorityBooster.boost();
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 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 com.android.server.wm;
|
||||||
|
|
||||||
|
import static android.os.Process.THREAD_PRIORITY_DISPLAY;
|
||||||
|
import static android.os.Process.myTid;
|
||||||
|
import static android.os.Process.setThreadPriority;
|
||||||
|
|
||||||
|
import static com.android.server.LockGuard.INDEX_WINDOW;
|
||||||
|
import static com.android.server.am.ActivityManagerService.TOP_APP_PRIORITY_BOOST;
|
||||||
|
|
||||||
|
import com.android.server.AnimationThread;
|
||||||
|
import com.android.server.ThreadPriorityBooster;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Window manager version of {@link ThreadPriorityBooster} that boosts even more during app
|
||||||
|
* transitions.
|
||||||
|
*/
|
||||||
|
class WindowManagerThreadPriorityBooster extends ThreadPriorityBooster {
|
||||||
|
|
||||||
|
private final AnimationThread mAnimationThread;
|
||||||
|
private boolean mAppTransitionRunning;
|
||||||
|
|
||||||
|
WindowManagerThreadPriorityBooster() {
|
||||||
|
super(THREAD_PRIORITY_DISPLAY, INDEX_WINDOW);
|
||||||
|
mAnimationThread = AnimationThread.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void boost() {
|
||||||
|
|
||||||
|
// Do not boost the animation thread. As the animation thread is changing priorities,
|
||||||
|
// boosting it might mess up the priority because we reset it the the previous priority.
|
||||||
|
if (myTid() == mAnimationThread.getThreadId()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.boost();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {
|
||||||
|
|
||||||
|
// See comment in boost().
|
||||||
|
if (myTid() == mAnimationThread.getThreadId()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
super.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAppTransitionRunning(boolean running) {
|
||||||
|
if (mAppTransitionRunning == running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int priority = calculatePriority(running);
|
||||||
|
setBoostToPriority(priority);
|
||||||
|
setThreadPriority(mAnimationThread.getThreadId(), priority);
|
||||||
|
mAppTransitionRunning = running;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int calculatePriority(boolean appTransitionRunning) {
|
||||||
|
return appTransitionRunning ? TOP_APP_PRIORITY_BOOST : THREAD_PRIORITY_DISPLAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user