Skip to content

Commit 3a8effb

Browse files
Jeff BrownAndroid Git Automerger
authored andcommitted
am 9302251: Merge "Reduce screen on latency, eliminate flashes." into jb-mr1-dev
* commit '9302251e3a09810164895237a6a2e8ac4987c3c0': Reduce screen on latency, eliminate flashes.
2 parents e71a630 + 9302251 commit 3a8effb

File tree

5 files changed

+116
-70
lines changed

5 files changed

+116
-70
lines changed

services/java/com/android/server/power/DisplayPowerController.java

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,12 @@ final class DisplayPowerController {
271271
// When the screen turns on again, we report user activity to the power manager.
272272
private boolean mScreenOffBecauseOfProximity;
273273

274+
// True if the screen on is being blocked.
275+
private boolean mScreenOnWasBlocked;
276+
277+
// The elapsed real time when the screen on was blocked.
278+
private long mScreenOnBlockStartRealTime;
279+
274280
// Set to true if the light sensor is enabled.
275281
private boolean mLightSensorEnabled;
276282

@@ -513,7 +519,7 @@ private void initialize() {
513519
final Executor executor = AsyncTask.THREAD_POOL_EXECUTOR;
514520
Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
515521
mPowerState = new DisplayPowerState(
516-
mElectronBeamAnimatesBacklightConfig ? null : new ElectronBeam(display),
522+
new ElectronBeam(display),
517523
new PhotonicModulator(executor,
518524
mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT),
519525
mSuspendBlocker));
@@ -553,7 +559,6 @@ private void updatePowerState() {
553559
final boolean mustNotify;
554560
boolean mustInitialize = false;
555561
boolean updateAutoBrightness = mTwilightChanged;
556-
boolean screenOnWasBlocked = false;
557562
mTwilightChanged = false;
558563

559564
synchronized (mLock) {
@@ -662,18 +667,24 @@ private void updatePowerState() {
662667
// It is relatively short but if we cancel it and switch to the
663668
// on animation immediately then the results are pretty ugly.
664669
if (!mElectronBeamOffAnimator.isStarted()) {
665-
if (mPowerRequest.blockScreenOn && !mPowerState.isScreenOn()) {
666-
if (DEBUG) {
667-
Slog.d(TAG, "Blocked screen on while screen currently off.");
668-
}
669-
screenOnWasBlocked = true;
670+
// Turn the screen on. The contents of the screen may not yet
671+
// be visible if the electron beam has not been dismissed because
672+
// its last frame of animation is solid black.
673+
setScreenOn(true);
674+
675+
if (mPowerRequest.blockScreenOn
676+
&& mPowerState.getElectronBeamLevel() == 0.0f) {
677+
blockScreenOn();
670678
} else {
671-
setScreenOn(true);
679+
unblockScreenOn();
672680
if (USE_ELECTRON_BEAM_ON_ANIMATION) {
673681
if (!mElectronBeamOnAnimator.isStarted()) {
674682
if (mPowerState.getElectronBeamLevel() == 1.0f) {
675683
mPowerState.dismissElectronBeam();
676-
} else if (mPowerState.prepareElectronBeam(true)) {
684+
} else if (mPowerState.prepareElectronBeam(
685+
mElectronBeamAnimatesBacklightConfig ?
686+
ElectronBeam.MODE_BLANK :
687+
ElectronBeam.MODE_WARM_UP)) {
677688
mElectronBeamOnAnimator.start();
678689
} else {
679690
mElectronBeamOnAnimator.end();
@@ -684,22 +695,6 @@ private void updatePowerState() {
684695
mPowerState.dismissElectronBeam();
685696
}
686697
}
687-
} else {
688-
// FIXME: If the electron beam off animation is playing then we have a bit
689-
// of a problem. The window manager policy would only have requested
690-
// to block screen on if it was about to start preparing the keyguard.
691-
// It's already too late to do anything about that. Ideally we would
692-
// let the animation play out first but that would require making
693-
// some pretty deep changes to the power manager and we don't have
694-
// time just now. For now, short-circuit the animation and get ready.
695-
if (mPowerRequest.blockScreenOn) {
696-
if (DEBUG) {
697-
Slog.d(TAG, "Blocked screen on while screen off animation running.");
698-
}
699-
screenOnWasBlocked = true;
700-
setScreenOn(false);
701-
mElectronBeamOffAnimator.end();
702-
}
703698
}
704699
} else {
705700
// Want screen off.
@@ -708,7 +703,10 @@ private void updatePowerState() {
708703
if (!mElectronBeamOffAnimator.isStarted()) {
709704
if (mPowerState.getElectronBeamLevel() == 0.0f) {
710705
setScreenOn(false);
711-
} else if (mPowerState.prepareElectronBeam(false)
706+
} else if (mPowerState.prepareElectronBeam(
707+
mElectronBeamAnimatesBacklightConfig ?
708+
ElectronBeam.MODE_BLANK :
709+
ElectronBeam.MODE_COOL_DOWN)
712710
&& mPowerState.isScreenOn()) {
713711
mElectronBeamOffAnimator.start();
714712
} else {
@@ -723,7 +721,7 @@ private void updatePowerState() {
723721
// We mostly care about the screen state here, ignoring brightness changes
724722
// which will be handled asynchronously.
725723
if (mustNotify
726-
&& !screenOnWasBlocked
724+
&& !mScreenOnWasBlocked
727725
&& !mElectronBeamOnAnimator.isStarted()
728726
&& !mElectronBeamOffAnimator.isStarted()
729727
&& mPowerState.waitUntilClean(mCleanListener)) {
@@ -740,6 +738,26 @@ private void updatePowerState() {
740738
}
741739
}
742740

741+
private void blockScreenOn() {
742+
if (!mScreenOnWasBlocked) {
743+
mScreenOnWasBlocked = true;
744+
if (DEBUG) {
745+
Slog.d(TAG, "Blocked screen on.");
746+
mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
747+
}
748+
}
749+
}
750+
751+
private void unblockScreenOn() {
752+
if (mScreenOnWasBlocked) {
753+
mScreenOnWasBlocked = false;
754+
if (DEBUG) {
755+
Slog.d(TAG, "Unblocked screen on after " +
756+
(SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime) + " ms");
757+
}
758+
}
759+
}
760+
743761
private void setScreenOn(boolean on) {
744762
if (!mPowerState.isScreenOn() == on) {
745763
mPowerState.setScreenOn(on);

services/java/com/android/server/power/DisplayPowerRequest.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,14 @@ final class DisplayPowerRequest {
5252
// If true, enables automatic brightness control.
5353
public boolean useAutoBrightness;
5454

55-
// If true, prevents the screen from turning on if it is currently off.
56-
// The display does not enter a "ready" state if this flag is true and the screen
57-
// is off and is being prevented from turning on. The window manager policy blocks
58-
// screen on while it prepares the keyguard to prevent the user from seeing
59-
// intermediate updates.
55+
// If true, prevents the screen from completely turning on if it is currently off.
56+
// The display does not enter a "ready" state if this flag is true and screen on is
57+
// blocked. The window manager policy blocks screen on while it prepares the keyguard to
58+
// prevent the user from seeing intermediate updates.
59+
//
60+
// Technically, we may not block the screen itself from turning on (because that introduces
61+
// extra unnecessary latency) but we do prevent content on screen from becoming
62+
// visible to the user.
6063
public boolean blockScreenOn;
6164

6265
public DisplayPowerRequest() {

services/java/com/android/server/power/DisplayPowerState.java

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ final class DisplayPowerState {
5050
private static final int DIRTY_BRIGHTNESS = 1 << 2;
5151

5252
private final Choreographer mChoreographer;
53-
private final ElectronBeam mElectronBeam; // may be null if only animating backlights
53+
private final ElectronBeam mElectronBeam;
5454
private final PhotonicModulator mScreenBrightnessModulator;
5555

5656
private int mDirty;
@@ -130,26 +130,19 @@ public boolean isScreenOn() {
130130
* This method should be called before starting an animation because it
131131
* can take a fair amount of time to prepare the electron beam surface.
132132
*
133-
* @param warmUp True if the electron beam should start warming up.
133+
* @param mode The electron beam animation mode to prepare.
134134
* @return True if the electron beam was prepared.
135135
*/
136-
public boolean prepareElectronBeam(boolean warmUp) {
137-
if (mElectronBeam != null) {
138-
boolean success = mElectronBeam.prepare(warmUp);
139-
invalidate(DIRTY_ELECTRON_BEAM);
140-
return success;
141-
} else {
142-
return true;
143-
}
136+
public boolean prepareElectronBeam(int mode) {
137+
invalidate(DIRTY_ELECTRON_BEAM);
138+
return mElectronBeam.prepare(mode);
144139
}
145140

146141
/**
147142
* Dismisses the electron beam surface.
148143
*/
149144
public void dismissElectronBeam() {
150-
if (mElectronBeam != null) {
151-
mElectronBeam.dismiss();
152-
}
145+
mElectronBeam.dismiss();
153146
}
154147

155148
/**
@@ -230,9 +223,7 @@ public void dump(PrintWriter pw) {
230223
pw.println(" mScreenBrightness=" + mScreenBrightness);
231224
pw.println(" mElectronBeamLevel=" + mElectronBeamLevel);
232225

233-
if (mElectronBeam != null) {
234-
mElectronBeam.dump(pw);
235-
}
226+
mElectronBeam.dump(pw);
236227
}
237228

238229
private void invalidate(int dirty) {
@@ -251,7 +242,7 @@ private void apply() {
251242
PowerManagerService.nativeSetScreenState(false);
252243
}
253244

254-
if ((mDirty & DIRTY_ELECTRON_BEAM) != 0 && mElectronBeam != null) {
245+
if ((mDirty & DIRTY_ELECTRON_BEAM) != 0) {
255246
mElectronBeam.draw(mElectronBeamLevel);
256247
}
257248

0 commit comments

Comments
 (0)