Merge "Add two new display info fields"
This commit is contained in:
committed by
Android (Google) Code Review
commit
50b9fcfae1
@@ -598,6 +598,42 @@ public final class Display {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the app VSYNC offset, in nanoseconds. This is a positive value indicating
|
||||
* the phase offset of the VSYNC events provided by Choreographer relative to the
|
||||
* display refresh. For example, if Choreographer reports that the refresh occurred
|
||||
* at time N, it actually occurred at (N - appVsyncOffset).
|
||||
* <p>
|
||||
* Apps generally do not need to be aware of this. It's only useful for fine-grained
|
||||
* A/V synchronization.
|
||||
* @hide
|
||||
*/
|
||||
public long getAppVsyncOffsetNanos() {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
return mDisplayInfo.appVsyncOffsetNanos;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is how far in advance a buffer must be queued for presentation at
|
||||
* a given time. If you want a buffer to appear on the screen at
|
||||
* time N, you must submit the buffer before (N - presentationDeadline).
|
||||
* <p>
|
||||
* The desired presentation time for GLES rendering may be set with
|
||||
* {@link android.opengl.EGLExt#eglPresentationTimeANDROID}. For video decoding, use
|
||||
* {@link android.media.MediaCodec#releaseOutputBuffer(int, long)}. Times are
|
||||
* expressed in nanoseconds, using the system monotonic clock
|
||||
* ({@link System#nanoTime}).
|
||||
* @hide
|
||||
*/
|
||||
public long getPresentationDeadlineNanos() {
|
||||
synchronized (this) {
|
||||
updateDisplayInfoLocked();
|
||||
return mDisplayInfo.presentationDeadlineNanos;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets display metrics that describe the size and density of this display.
|
||||
* <p>
|
||||
|
||||
@@ -179,6 +179,20 @@ public final class DisplayInfo implements Parcelable {
|
||||
*/
|
||||
public float physicalYDpi;
|
||||
|
||||
/**
|
||||
* This is a positive value indicating the phase offset of the VSYNC events provided by
|
||||
* Choreographer relative to the display refresh. For example, if Choreographer reports
|
||||
* that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
|
||||
*/
|
||||
public long appVsyncOffsetNanos;
|
||||
|
||||
/**
|
||||
* This is how far in advance a buffer must be queued for presentation at
|
||||
* a given time. If you want a buffer to appear on the screen at
|
||||
* time N, you must submit the buffer before (N - bufferDeadlineNanos).
|
||||
*/
|
||||
public long presentationDeadlineNanos;
|
||||
|
||||
/**
|
||||
* The state of the display, such as {@link android.view.Display#STATE_ON}.
|
||||
*/
|
||||
@@ -253,6 +267,8 @@ public final class DisplayInfo implements Parcelable {
|
||||
&& logicalDensityDpi == other.logicalDensityDpi
|
||||
&& physicalXDpi == other.physicalXDpi
|
||||
&& physicalYDpi == other.physicalYDpi
|
||||
&& appVsyncOffsetNanos == other.appVsyncOffsetNanos
|
||||
&& presentationDeadlineNanos == other.presentationDeadlineNanos
|
||||
&& state == other.state
|
||||
&& ownerUid == other.ownerUid
|
||||
&& Objects.equal(ownerPackageName, other.ownerPackageName);
|
||||
@@ -286,6 +302,8 @@ public final class DisplayInfo implements Parcelable {
|
||||
logicalDensityDpi = other.logicalDensityDpi;
|
||||
physicalXDpi = other.physicalXDpi;
|
||||
physicalYDpi = other.physicalYDpi;
|
||||
appVsyncOffsetNanos = other.appVsyncOffsetNanos;
|
||||
presentationDeadlineNanos = other.presentationDeadlineNanos;
|
||||
state = other.state;
|
||||
ownerUid = other.ownerUid;
|
||||
ownerPackageName = other.ownerPackageName;
|
||||
@@ -314,6 +332,8 @@ public final class DisplayInfo implements Parcelable {
|
||||
logicalDensityDpi = source.readInt();
|
||||
physicalXDpi = source.readFloat();
|
||||
physicalYDpi = source.readFloat();
|
||||
appVsyncOffsetNanos = source.readLong();
|
||||
presentationDeadlineNanos = source.readLong();
|
||||
state = source.readInt();
|
||||
ownerUid = source.readInt();
|
||||
ownerPackageName = source.readString();
|
||||
@@ -343,6 +363,8 @@ public final class DisplayInfo implements Parcelable {
|
||||
dest.writeInt(logicalDensityDpi);
|
||||
dest.writeFloat(physicalXDpi);
|
||||
dest.writeFloat(physicalYDpi);
|
||||
dest.writeLong(appVsyncOffsetNanos);
|
||||
dest.writeLong(presentationDeadlineNanos);
|
||||
dest.writeInt(state);
|
||||
dest.writeInt(ownerUid);
|
||||
dest.writeString(ownerPackageName);
|
||||
@@ -450,6 +472,10 @@ public final class DisplayInfo implements Parcelable {
|
||||
sb.append(physicalYDpi);
|
||||
sb.append(") dpi, layerStack ");
|
||||
sb.append(layerStack);
|
||||
sb.append(", appVsyncOff ");
|
||||
sb.append(appVsyncOffsetNanos);
|
||||
sb.append(", presDeadline ");
|
||||
sb.append(presentationDeadlineNanos);
|
||||
sb.append(", type ");
|
||||
sb.append(Display.typeToString(type));
|
||||
if (address != null) {
|
||||
|
||||
@@ -458,6 +458,8 @@ public class SurfaceControl {
|
||||
public float xDpi;
|
||||
public float yDpi;
|
||||
public boolean secure;
|
||||
public long appVsyncOffsetNanos;
|
||||
public long presentationDeadlineNanos;
|
||||
|
||||
public PhysicalDisplayInfo() {
|
||||
}
|
||||
@@ -479,7 +481,9 @@ public class SurfaceControl {
|
||||
&& density == other.density
|
||||
&& xDpi == other.xDpi
|
||||
&& yDpi == other.yDpi
|
||||
&& secure == other.secure;
|
||||
&& secure == other.secure
|
||||
&& appVsyncOffsetNanos == other.appVsyncOffsetNanos
|
||||
&& presentationDeadlineNanos == other.presentationDeadlineNanos;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -495,6 +499,8 @@ public class SurfaceControl {
|
||||
xDpi = other.xDpi;
|
||||
yDpi = other.yDpi;
|
||||
secure = other.secure;
|
||||
appVsyncOffsetNanos = other.appVsyncOffsetNanos;
|
||||
presentationDeadlineNanos = other.presentationDeadlineNanos;
|
||||
}
|
||||
|
||||
// For debugging purposes
|
||||
@@ -502,7 +508,8 @@ public class SurfaceControl {
|
||||
public String toString() {
|
||||
return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
|
||||
+ "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
|
||||
+ "}";
|
||||
+ ", appVsyncOffset " + appVsyncOffsetNanos
|
||||
+ ", bufferDeadline " + presentationDeadlineNanos + "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ static struct {
|
||||
jfieldID xDpi;
|
||||
jfieldID yDpi;
|
||||
jfieldID secure;
|
||||
jfieldID appVsyncOffsetNanos;
|
||||
jfieldID presentationDeadlineNanos;
|
||||
} gPhysicalDisplayInfoClassInfo;
|
||||
|
||||
static struct {
|
||||
@@ -392,6 +394,10 @@ static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz,
|
||||
env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi);
|
||||
env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi);
|
||||
env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure);
|
||||
env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos,
|
||||
info.appVsyncOffset);
|
||||
env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos,
|
||||
info.presentationDeadline);
|
||||
env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj);
|
||||
env->DeleteLocalRef(infoObj);
|
||||
}
|
||||
@@ -648,6 +654,10 @@ int register_android_view_SurfaceControl(JNIEnv* env)
|
||||
gPhysicalDisplayInfoClassInfo.xDpi = env->GetFieldID(clazz, "xDpi", "F");
|
||||
gPhysicalDisplayInfoClassInfo.yDpi = env->GetFieldID(clazz, "yDpi", "F");
|
||||
gPhysicalDisplayInfoClassInfo.secure = env->GetFieldID(clazz, "secure", "Z");
|
||||
gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos = env->GetFieldID(clazz,
|
||||
"appVsyncOffsetNanos", "J");
|
||||
gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos = env->GetFieldID(clazz,
|
||||
"presentationDeadlineNanos", "J");
|
||||
|
||||
jclass rectClazz = env->FindClass("android/graphics/Rect");
|
||||
gRectClassInfo.bottom = env->GetFieldID(rectClazz, "bottom", "I");
|
||||
|
||||
@@ -119,7 +119,7 @@ final class DisplayDeviceInfo {
|
||||
public int height;
|
||||
|
||||
/**
|
||||
* The refresh rate of the display.
|
||||
* The refresh rate of the display, in frames per second.
|
||||
*/
|
||||
public float refreshRate;
|
||||
|
||||
@@ -143,6 +143,20 @@ final class DisplayDeviceInfo {
|
||||
*/
|
||||
public float yDpi;
|
||||
|
||||
/**
|
||||
* This is a positive value indicating the phase offset of the VSYNC events provided by
|
||||
* Choreographer relative to the display refresh. For example, if Choreographer reports
|
||||
* that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
|
||||
*/
|
||||
public long appVsyncOffsetNanos;
|
||||
|
||||
/**
|
||||
* This is how far in advance a buffer must be queued for presentation at
|
||||
* a given time. If you want a buffer to appear on the screen at
|
||||
* time N, you must submit the buffer before (N - bufferDeadlineNanos).
|
||||
*/
|
||||
public long presentationDeadlineNanos;
|
||||
|
||||
/**
|
||||
* Display flags.
|
||||
*/
|
||||
@@ -219,6 +233,8 @@ final class DisplayDeviceInfo {
|
||||
&& densityDpi == other.densityDpi
|
||||
&& xDpi == other.xDpi
|
||||
&& yDpi == other.yDpi
|
||||
&& appVsyncOffsetNanos == other.appVsyncOffsetNanos
|
||||
&& presentationDeadlineNanos == other.presentationDeadlineNanos
|
||||
&& flags == other.flags
|
||||
&& touch == other.touch
|
||||
&& rotation == other.rotation
|
||||
@@ -242,6 +258,8 @@ final class DisplayDeviceInfo {
|
||||
densityDpi = other.densityDpi;
|
||||
xDpi = other.xDpi;
|
||||
yDpi = other.yDpi;
|
||||
appVsyncOffsetNanos = other.appVsyncOffsetNanos;
|
||||
presentationDeadlineNanos = other.presentationDeadlineNanos;
|
||||
flags = other.flags;
|
||||
touch = other.touch;
|
||||
rotation = other.rotation;
|
||||
@@ -261,6 +279,8 @@ final class DisplayDeviceInfo {
|
||||
sb.append(", ").append(refreshRate).append(" fps, ");
|
||||
sb.append("density ").append(densityDpi);
|
||||
sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
|
||||
sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
|
||||
sb.append(", presDeadline ").append(presentationDeadlineNanos);
|
||||
sb.append(", touch ").append(touchToString(touch));
|
||||
sb.append(", rotation ").append(rotation);
|
||||
sb.append(", type ").append(Display.typeToString(type));
|
||||
|
||||
@@ -161,6 +161,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
mInfo.width = mPhys.width;
|
||||
mInfo.height = mPhys.height;
|
||||
mInfo.refreshRate = mPhys.refreshRate;
|
||||
mInfo.appVsyncOffsetNanos = mPhys.appVsyncOffsetNanos;
|
||||
mInfo.presentationDeadlineNanos = mPhys.presentationDeadlineNanos;
|
||||
mInfo.state = mState;
|
||||
|
||||
// Assume that all built-in displays that have secure output (eg. HDCP) also
|
||||
|
||||
@@ -213,6 +213,8 @@ final class LogicalDisplay {
|
||||
mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
|
||||
mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
|
||||
mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
|
||||
mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
|
||||
mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
|
||||
mBaseDisplayInfo.state = deviceInfo.state;
|
||||
mBaseDisplayInfo.smallestNominalAppWidth = deviceInfo.width;
|
||||
mBaseDisplayInfo.smallestNominalAppHeight = deviceInfo.height;
|
||||
|
||||
@@ -191,6 +191,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
||||
private final int mWidth;
|
||||
private final int mHeight;
|
||||
private final float mRefreshRate;
|
||||
private final long mDisplayPresentationDeadlineNanos;
|
||||
private final int mDensityDpi;
|
||||
private final boolean mSecure;
|
||||
|
||||
@@ -200,7 +201,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
||||
private DisplayDeviceInfo mInfo;
|
||||
|
||||
public OverlayDisplayDevice(IBinder displayToken, String name,
|
||||
int width, int height, float refreshRate,
|
||||
int width, int height, float refreshRate, long presentationDeadlineNanos,
|
||||
int densityDpi, boolean secure, int state,
|
||||
SurfaceTexture surfaceTexture) {
|
||||
super(OverlayDisplayAdapter.this, displayToken);
|
||||
@@ -208,6 +209,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mRefreshRate = refreshRate;
|
||||
mDisplayPresentationDeadlineNanos = presentationDeadlineNanos;
|
||||
mDensityDpi = densityDpi;
|
||||
mSecure = secure;
|
||||
mState = state;
|
||||
@@ -249,6 +251,8 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
||||
mInfo.densityDpi = mDensityDpi;
|
||||
mInfo.xDpi = mDensityDpi;
|
||||
mInfo.yDpi = mDensityDpi;
|
||||
mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos +
|
||||
1000000000L / (int) mRefreshRate; // display's deadline + 1 frame
|
||||
mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION;
|
||||
if (mSecure) {
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_SECURE;
|
||||
@@ -297,12 +301,13 @@ final class OverlayDisplayAdapter extends DisplayAdapter {
|
||||
|
||||
// Called on the UI thread.
|
||||
@Override
|
||||
public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate, int state) {
|
||||
public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate,
|
||||
long presentationDeadlineNanos, int state) {
|
||||
synchronized (getSyncRoot()) {
|
||||
IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure);
|
||||
mDevice = new OverlayDisplayDevice(displayToken, mName,
|
||||
mWidth, mHeight, refreshRate, mDensityDpi, mSecure,
|
||||
state, surfaceTexture);
|
||||
mWidth, mHeight, refreshRate, presentationDeadlineNanos,
|
||||
mDensityDpi, mSecure, state, surfaceTexture);
|
||||
|
||||
sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ final class OverlayDisplayWindow implements DumpUtils.Dump {
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
|
||||
int width, int height) {
|
||||
mListener.onWindowCreated(surfaceTexture, mDefaultDisplayInfo.refreshRate,
|
||||
mDefaultDisplayInfo.state);
|
||||
mDefaultDisplayInfo.presentationDeadlineNanos, mDefaultDisplayInfo.state);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -373,7 +373,7 @@ final class OverlayDisplayWindow implements DumpUtils.Dump {
|
||||
*/
|
||||
public interface Listener {
|
||||
public void onWindowCreated(SurfaceTexture surfaceTexture,
|
||||
float refreshRate, int state);
|
||||
float refreshRate, long presentationDeadlineNanos, int state);
|
||||
public void onWindowDestroyed();
|
||||
public void onStateChanged(int state);
|
||||
}
|
||||
|
||||
@@ -171,6 +171,7 @@ final class VirtualDisplayAdapter extends DisplayAdapter {
|
||||
mInfo.densityDpi = mDensityDpi;
|
||||
mInfo.xDpi = mDensityDpi;
|
||||
mInfo.yDpi = mDensityDpi;
|
||||
mInfo.presentationDeadlineNanos = 1000000000L / (int) mInfo.refreshRate; // 1 frame
|
||||
mInfo.flags = 0;
|
||||
if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
|
||||
mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE
|
||||
|
||||
@@ -127,7 +127,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
|
||||
pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast);
|
||||
pw.println("mPendingNotificationUpdate=" + mPendingNotificationUpdate);
|
||||
pw.println("mSupportsProtectedBuffers=" + mSupportsProtectedBuffers);
|
||||
|
||||
|
||||
// Try to dump the controller state.
|
||||
if (mDisplayController == null) {
|
||||
pw.println("mDisplayController=null");
|
||||
@@ -729,6 +729,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
|
||||
mInfo.width = mWidth;
|
||||
mInfo.height = mHeight;
|
||||
mInfo.refreshRate = mRefreshRate;
|
||||
mInfo.presentationDeadlineNanos = 1000000000L / (int) mRefreshRate; // 1 frame
|
||||
mInfo.flags = mFlags;
|
||||
mInfo.type = Display.TYPE_WIFI;
|
||||
mInfo.address = mAddress;
|
||||
|
||||
Reference in New Issue
Block a user