Ignore draw requests when the display is off

When WindowManagerService's events are enabled/disabled, the state of the
display is dispatched to the known windows. This allows ViewRootImpl to
ignore draw requests until the screen is turned back on. This can potentially
lead to significant battery savings. For instance, a launcher widget showing
a repeating animation will cause the CPU and the GPU to wake up regularly
without this change.
(Change submitted by Intel and merged manually)

Change-Id: I7f93b0e60c3e6de1705f619e80860c36b1cdb978
This commit is contained in:
Romain Guy
2012-03-05 14:37:29 -08:00
parent fb9c41c206
commit 7e4e561bc7
5 changed files with 58 additions and 2 deletions

View File

@@ -49,6 +49,7 @@ oneway interface IWindow {
boolean reportDraw, in Configuration newConfig);
void dispatchAppVisibility(boolean visible);
void dispatchGetNewSurface();
void dispatchScreenStatus(boolean on);
/**
* Tell the window that it is either gaining or losing focus. Keep it up

View File

@@ -14845,6 +14845,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
boolean mHardwareAccelerationRequested;
HardwareRenderer mHardwareRenderer;
boolean mScreenOn;
/**
* Scale factor used by the compatibility mode
*/

View File

@@ -46,6 +46,7 @@ import android.os.LatencyTimer;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -390,6 +391,9 @@ public final class ViewRootImpl implements ViewParent,
mProfileRendering = Boolean.parseBoolean(
SystemProperties.get(PROPERTY_PROFILE_RENDERING, "false"));
mChoreographer = Choreographer.getInstance();
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mAttachInfo.mScreenOn = powerManager.isScreenOn();
}
/**
@@ -757,6 +761,16 @@ public final class ViewRootImpl implements ViewParent,
scheduleTraversals();
}
void handleScreenStatusChange(boolean on) {
if (on != mAttachInfo.mScreenOn) {
mAttachInfo.mScreenOn = on;
if (on) {
mFullRedrawNeeded = true;
scheduleTraversals();
}
}
}
/**
* {@inheritDoc}
*/
@@ -1886,6 +1900,8 @@ public final class ViewRootImpl implements ViewParent,
}
private void performDraw() {
if (!mAttachInfo.mScreenOn) return;
final long drawStartTime;
if (ViewDebug.DEBUG_LATENCY) {
drawStartTime = System.nanoTime();
@@ -2018,8 +2034,7 @@ public final class ViewRootImpl implements ViewParent,
}
if (!dirty.isEmpty() || mIsAnimating) {
if (mAttachInfo.mHardwareRenderer != null
&& mAttachInfo.mHardwareRenderer.isEnabled()) {
if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
// Draw with hardware renderer.
mIsAnimating = false;
mHardwareYOffset = yoff;
@@ -2485,6 +2500,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID = 21;
private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 22;
private final static int MSG_PROCESS_INPUT_EVENTS = 23;
private final static int MSG_DISPATCH_SCREEN_STATUS = 24;
final class ViewRootHandler extends Handler {
@Override
@@ -2741,6 +2757,11 @@ public final class ViewRootImpl implements ViewParent,
.findAccessibilityNodeInfosByTextUiThread(msg);
}
} break;
case MSG_DISPATCH_SCREEN_STATUS: {
if (mView != null) {
handleScreenStatusChange(msg.arg1 == 1);
}
} break;
}
}
}
@@ -4025,6 +4046,12 @@ public final class ViewRootImpl implements ViewParent,
mHandler.sendMessage(msg);
}
public void dispatchScreenStatusChange(boolean on) {
Message msg = mHandler.obtainMessage(MSG_DISPATCH_SCREEN_STATUS);
msg.arg1 = on ? 1 : 0;
mHandler.sendMessage(msg);
}
public void dispatchGetNewSurface() {
Message msg = mHandler.obtainMessage(MSG_DISPATCH_GET_NEW_SURFACE);
mHandler.sendMessage(msg);
@@ -4226,6 +4253,13 @@ public final class ViewRootImpl implements ViewParent,
}
}
public void dispatchScreenStatus(boolean on) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.dispatchScreenStatusChange(on);
}
}
public void dispatchGetNewSurface() {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {

View File

@@ -49,6 +49,9 @@ public class BaseIWindow extends IWindow.Stub {
public void dispatchGetNewSurface() {
}
public void dispatchScreenStatus(boolean on) {
}
public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
}