am 1e713c19: am 984bed19: am 1e7be6f4: am e43684a6: am 42ecd144: Merge "Move setting the display state out of the critical section." into lmp-dev

* commit '1e713c191ce93ca5c5a1e50e332b29e04e4035f4':
  Move setting the display state out of the critical section.
This commit is contained in:
Jeff Brown
2014-09-23 21:43:14 +00:00
committed by Android Git Automerger
4 changed files with 61 additions and 19 deletions

View File

@@ -108,8 +108,12 @@ abstract class DisplayDevice {
/**
* Sets the display state, if supported.
*
* @return A runnable containing work to be deferred until after we have
* exited the critical section, or null if none.
*/
public void requestDisplayStateLocked(int state) {
public Runnable requestDisplayStateLocked(int state) {
return null;
}
/**

View File

@@ -63,6 +63,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -214,6 +215,11 @@ public final class DisplayManagerService extends SystemService {
private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
// Temporary list of deferred work to perform when setting the display state.
// Only used by requestDisplayState. The field is self-synchronized and only
// intended for use inside of the requestGlobalDisplayStateInternal function.
private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>();
public DisplayManagerService(Context context) {
super(context);
mContext = context;
@@ -318,11 +324,26 @@ public final class DisplayManagerService extends SystemService {
}
private void requestGlobalDisplayStateInternal(int state) {
synchronized (mSyncRoot) {
if (mGlobalDisplayState != state) {
mGlobalDisplayState = state;
updateGlobalDisplayStateLocked();
scheduleTraversalLocked(false);
synchronized (mTempDisplayStateWorkQueue) {
try {
// Update the display state within the lock.
synchronized (mSyncRoot) {
if (mGlobalDisplayState != state) {
mGlobalDisplayState = state;
updateGlobalDisplayStateLocked(mTempDisplayStateWorkQueue);
scheduleTraversalLocked(false);
}
}
// Setting the display power state can take hundreds of milliseconds
// to complete so we defer the most expensive part of the work until
// after we have exited the critical section to avoid blocking other
// threads for a long time.
for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) {
mTempDisplayStateWorkQueue.get(i).run();
}
} finally {
mTempDisplayStateWorkQueue.clear();
}
}
}
@@ -669,21 +690,25 @@ public final class DisplayManagerService extends SystemService {
scheduleTraversalLocked(false);
}
private void updateGlobalDisplayStateLocked() {
private void updateGlobalDisplayStateLocked(List<Runnable> workQueue) {
final int count = mDisplayDevices.size();
for (int i = 0; i < count; i++) {
DisplayDevice device = mDisplayDevices.get(i);
updateDisplayStateLocked(device);
Runnable runnable = updateDisplayStateLocked(device);
if (runnable != null) {
workQueue.add(runnable);
}
}
}
private void updateDisplayStateLocked(DisplayDevice device) {
private Runnable updateDisplayStateLocked(DisplayDevice device) {
// Blank or unblank the display immediately to match the state requested
// by the display power controller (if known).
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) {
device.requestDisplayStateLocked(mGlobalDisplayState);
return device.requestDisplayStateLocked(mGlobalDisplayState);
}
return null;
}
// Adds a new logical display based on the given display device.

View File

@@ -222,19 +222,31 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
@Override
public void requestDisplayStateLocked(int state) {
public Runnable requestDisplayStateLocked(final int state) {
if (mState != state) {
final int displayId = mBuiltInDisplayId;
final IBinder token = getDisplayTokenLocked();
final int mode = getPowerModeForState(state);
Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
+ Display.stateToString(state) + ", id=" + mBuiltInDisplayId + ")");
try {
SurfaceControl.setDisplayPowerMode(getDisplayTokenLocked(), mode);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
mState = state;
updateDeviceInfoLocked();
// Defer actually setting the display power mode until we have exited
// the critical section since it can take hundreds of milliseconds
// to complete.
return new Runnable() {
@Override
public void run() {
Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestDisplayState("
+ Display.stateToString(state) + ", id=" + displayId + ")");
try {
SurfaceControl.setDisplayPowerMode(token, mode);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
}
};
}
return null;
}
@Override

View File

@@ -188,7 +188,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
}
@Override
public void requestDisplayStateLocked(int state) {
public Runnable requestDisplayStateLocked(int state) {
if (state != mDisplayState) {
mDisplayState = state;
if (state == Display.STATE_OFF) {
@@ -197,6 +197,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
mCallback.dispatchDisplayResumed();
}
}
return null;
}
@Override