Merge changes Ib132c1e2,I2115f086 into udc-dev
* changes: Revert "Remove JNI per-frame allocations in Choreographer" Revert "Copy from DisplayEventReceiver.VsyncEventData"
This commit is contained in:
@@ -195,7 +195,7 @@ public final class Choreographer {
|
||||
|
||||
private boolean mDebugPrintNextFrameTimeDelta;
|
||||
private int mFPSDivisor = 1;
|
||||
private final DisplayEventReceiver.VsyncEventData mLastVsyncEventData =
|
||||
private DisplayEventReceiver.VsyncEventData mLastVsyncEventData =
|
||||
new DisplayEventReceiver.VsyncEventData();
|
||||
private final FrameData mFrameData = new FrameData();
|
||||
|
||||
@@ -857,7 +857,7 @@ public final class Choreographer {
|
||||
mFrameScheduled = false;
|
||||
mLastFrameTimeNanos = frameTimeNanos;
|
||||
mLastFrameIntervalNanos = frameIntervalNanos;
|
||||
mLastVsyncEventData.copyFrom(vsyncEventData);
|
||||
mLastVsyncEventData = vsyncEventData;
|
||||
}
|
||||
|
||||
AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
|
||||
@@ -1247,7 +1247,7 @@ public final class Choreographer {
|
||||
private boolean mHavePendingVsync;
|
||||
private long mTimestampNanos;
|
||||
private int mFrame;
|
||||
private final VsyncEventData mLastVsyncEventData = new VsyncEventData();
|
||||
private VsyncEventData mLastVsyncEventData = new VsyncEventData();
|
||||
|
||||
FrameDisplayEventReceiver(Looper looper, int vsyncSource, long layerHandle) {
|
||||
super(looper, vsyncSource, /* eventRegistration */ 0, layerHandle);
|
||||
@@ -1287,7 +1287,7 @@ public final class Choreographer {
|
||||
|
||||
mTimestampNanos = timestampNanos;
|
||||
mFrame = frame;
|
||||
mLastVsyncEventData.copyFrom(vsyncEventData);
|
||||
mLastVsyncEventData = vsyncEventData;
|
||||
Message msg = Message.obtain(mHandler, this);
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
|
||||
|
||||
@@ -81,10 +81,7 @@ public abstract class DisplayEventReceiver {
|
||||
// GC'd while the native peer of the receiver is using them.
|
||||
private MessageQueue mMessageQueue;
|
||||
|
||||
private final VsyncEventData mVsyncEventData = new VsyncEventData();
|
||||
|
||||
private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver,
|
||||
WeakReference<VsyncEventData> vsyncEventData,
|
||||
MessageQueue messageQueue, int vsyncSource, int eventRegistration, long layerHandle);
|
||||
private static native long nativeGetDisplayEventReceiverFinalizer();
|
||||
@FastNative
|
||||
@@ -127,9 +124,7 @@ public abstract class DisplayEventReceiver {
|
||||
}
|
||||
|
||||
mMessageQueue = looper.getQueue();
|
||||
mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this),
|
||||
new WeakReference<VsyncEventData>(mVsyncEventData),
|
||||
mMessageQueue,
|
||||
mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
|
||||
vsyncSource, eventRegistration, layerHandle);
|
||||
mFreeNativeResources = sNativeAllocationRegistry.registerNativeAllocation(this,
|
||||
mReceiverPtr);
|
||||
@@ -152,6 +147,9 @@ public abstract class DisplayEventReceiver {
|
||||
* @hide
|
||||
*/
|
||||
public static final class VsyncEventData {
|
||||
static final FrameTimeline[] INVALID_FRAME_TIMELINES =
|
||||
{new FrameTimeline(FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE, Long.MAX_VALUE)};
|
||||
|
||||
// The amount of frame timeline choices.
|
||||
// Must be in sync with VsyncEventData::kFrameTimelinesLength in
|
||||
// frameworks/native/libs/gui/include/gui/VsyncEventData.h. If they do not match, a runtime
|
||||
@@ -159,32 +157,22 @@ public abstract class DisplayEventReceiver {
|
||||
static final int FRAME_TIMELINES_LENGTH = 7;
|
||||
|
||||
public static class FrameTimeline {
|
||||
FrameTimeline() {}
|
||||
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
FrameTimeline(long vsyncId, long expectedPresentationTime, long deadline) {
|
||||
this.vsyncId = vsyncId;
|
||||
this.expectedPresentationTime = expectedPresentationTime;
|
||||
this.deadline = deadline;
|
||||
}
|
||||
|
||||
void copyFrom(FrameTimeline other) {
|
||||
vsyncId = other.vsyncId;
|
||||
expectedPresentationTime = other.expectedPresentationTime;
|
||||
deadline = other.deadline;
|
||||
}
|
||||
|
||||
// The frame timeline vsync id, used to correlate a frame
|
||||
// produced by HWUI with the timeline data stored in Surface Flinger.
|
||||
public long vsyncId = FrameInfo.INVALID_VSYNC_ID;
|
||||
public final long vsyncId;
|
||||
|
||||
// The frame timestamp for when the frame is expected to be presented.
|
||||
public long expectedPresentationTime = Long.MAX_VALUE;
|
||||
public final long expectedPresentationTime;
|
||||
|
||||
// The frame deadline timestamp in {@link System#nanoTime()} timebase that it is
|
||||
// allotted for the frame to be completed.
|
||||
public long deadline = Long.MAX_VALUE;
|
||||
public final long deadline;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,18 +180,11 @@ public abstract class DisplayEventReceiver {
|
||||
* {@link FrameInfo#VSYNC} to the current vsync in case Choreographer callback was heavily
|
||||
* delayed by the app.
|
||||
*/
|
||||
public long frameInterval = -1;
|
||||
public final long frameInterval;
|
||||
|
||||
public final FrameTimeline[] frameTimelines;
|
||||
|
||||
public int preferredFrameTimelineIndex = 0;
|
||||
|
||||
VsyncEventData() {
|
||||
frameTimelines = new FrameTimeline[FRAME_TIMELINES_LENGTH];
|
||||
for (int i = 0; i < frameTimelines.length; i++) {
|
||||
frameTimelines[i] = new FrameTimeline();
|
||||
}
|
||||
}
|
||||
public final int preferredFrameTimelineIndex;
|
||||
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
@@ -214,12 +195,10 @@ public abstract class DisplayEventReceiver {
|
||||
this.frameInterval = frameInterval;
|
||||
}
|
||||
|
||||
void copyFrom(VsyncEventData other) {
|
||||
preferredFrameTimelineIndex = other.preferredFrameTimelineIndex;
|
||||
frameInterval = other.frameInterval;
|
||||
for (int i = 0; i < frameTimelines.length; i++) {
|
||||
frameTimelines[i].copyFrom(other.frameTimelines[i]);
|
||||
}
|
||||
VsyncEventData() {
|
||||
this.frameInterval = -1;
|
||||
this.frameTimelines = INVALID_FRAME_TIMELINES;
|
||||
this.preferredFrameTimelineIndex = 0;
|
||||
}
|
||||
|
||||
public FrameTimeline preferredFrameTimeline() {
|
||||
@@ -325,8 +304,9 @@ public abstract class DisplayEventReceiver {
|
||||
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
|
||||
onVsync(timestampNanos, physicalDisplayId, frame, mVsyncEventData);
|
||||
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame,
|
||||
VsyncEventData vsyncEventData) {
|
||||
onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData);
|
||||
}
|
||||
|
||||
// Called from native code.
|
||||
|
||||
@@ -48,22 +48,12 @@ static struct {
|
||||
|
||||
struct {
|
||||
jclass clazz;
|
||||
|
||||
jmethodID init;
|
||||
|
||||
jfieldID vsyncId;
|
||||
jfieldID expectedPresentationTime;
|
||||
jfieldID deadline;
|
||||
} frameTimelineClassInfo;
|
||||
|
||||
struct {
|
||||
jclass clazz;
|
||||
|
||||
jmethodID init;
|
||||
|
||||
jfieldID frameInterval;
|
||||
jfieldID preferredFrameTimelineIndex;
|
||||
jfieldID frameTimelines;
|
||||
} vsyncEventDataClassInfo;
|
||||
|
||||
} gDisplayEventReceiverClassInfo;
|
||||
@@ -71,7 +61,7 @@ static struct {
|
||||
|
||||
class NativeDisplayEventReceiver : public DisplayEventDispatcher {
|
||||
public:
|
||||
NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, jobject vsyncEventDataWeak,
|
||||
NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
|
||||
const sp<MessageQueue>& messageQueue, jint vsyncSource,
|
||||
jint eventRegistration, jlong layerHandle);
|
||||
|
||||
@@ -82,7 +72,6 @@ protected:
|
||||
|
||||
private:
|
||||
jobject mReceiverWeakGlobal;
|
||||
jobject mVsyncEventDataWeakGlobal;
|
||||
sp<MessageQueue> mMessageQueue;
|
||||
|
||||
void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count,
|
||||
@@ -96,7 +85,6 @@ private:
|
||||
};
|
||||
|
||||
NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
|
||||
jobject vsyncEventDataWeak,
|
||||
const sp<MessageQueue>& messageQueue,
|
||||
jint vsyncSource, jint eventRegistration,
|
||||
jlong layerHandle)
|
||||
@@ -108,7 +96,6 @@ NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject rece
|
||||
reinterpret_cast<IBinder*>(layerHandle))
|
||||
: nullptr),
|
||||
mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
|
||||
mVsyncEventDataWeakGlobal(env->NewGlobalRef(vsyncEventDataWeak)),
|
||||
mMessageQueue(messageQueue) {
|
||||
ALOGV("receiver %p ~ Initializing display event receiver.", this);
|
||||
}
|
||||
@@ -167,43 +154,12 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
|
||||
ScopedLocalRef<jobject> vsyncEventDataObj(env, GetReferent(env, mVsyncEventDataWeakGlobal));
|
||||
if (receiverObj.get() && vsyncEventDataObj.get()) {
|
||||
if (receiverObj.get()) {
|
||||
ALOGV("receiver %p ~ Invoking vsync handler.", this);
|
||||
|
||||
env->SetIntField(vsyncEventDataObj.get(),
|
||||
gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo
|
||||
.preferredFrameTimelineIndex,
|
||||
vsyncEventData.preferredFrameTimelineIndex);
|
||||
env->SetLongField(vsyncEventDataObj.get(),
|
||||
gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameInterval,
|
||||
vsyncEventData.frameInterval);
|
||||
|
||||
ScopedLocalRef<jobjectArray>
|
||||
frameTimelinesObj(env,
|
||||
reinterpret_cast<jobjectArray>(
|
||||
env->GetObjectField(vsyncEventDataObj.get(),
|
||||
gDisplayEventReceiverClassInfo
|
||||
.vsyncEventDataClassInfo
|
||||
.frameTimelines)));
|
||||
for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
|
||||
VsyncEventData::FrameTimeline& frameTimeline = vsyncEventData.frameTimelines[i];
|
||||
ScopedLocalRef<jobject>
|
||||
frameTimelineObj(env, env->GetObjectArrayElement(frameTimelinesObj.get(), i));
|
||||
env->SetLongField(frameTimelineObj.get(),
|
||||
gDisplayEventReceiverClassInfo.frameTimelineClassInfo.vsyncId,
|
||||
frameTimeline.vsyncId);
|
||||
env->SetLongField(frameTimelineObj.get(),
|
||||
gDisplayEventReceiverClassInfo.frameTimelineClassInfo
|
||||
.expectedPresentationTime,
|
||||
frameTimeline.expectedPresentationTime);
|
||||
env->SetLongField(frameTimelineObj.get(),
|
||||
gDisplayEventReceiverClassInfo.frameTimelineClassInfo.deadline,
|
||||
frameTimeline.deadlineTimestamp);
|
||||
}
|
||||
|
||||
jobject javaVsyncEventData = createJavaVsyncEventData(env, vsyncEventData);
|
||||
env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,
|
||||
timestamp, displayId.value, count);
|
||||
timestamp, displayId.value, count, javaVsyncEventData);
|
||||
ALOGV("receiver %p ~ Returned from vsync handler.", this);
|
||||
}
|
||||
|
||||
@@ -271,9 +227,8 @@ void NativeDisplayEventReceiver::dispatchFrameRateOverrides(
|
||||
mMessageQueue->raiseAndClearException(env, "dispatchModeChanged");
|
||||
}
|
||||
|
||||
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject vsyncEventDataWeak,
|
||||
jobject messageQueueObj, jint vsyncSource, jint eventRegistration,
|
||||
jlong layerHandle) {
|
||||
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj,
|
||||
jint vsyncSource, jint eventRegistration, jlong layerHandle) {
|
||||
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
|
||||
if (messageQueue == NULL) {
|
||||
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
|
||||
@@ -281,8 +236,8 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject
|
||||
}
|
||||
|
||||
sp<NativeDisplayEventReceiver> receiver =
|
||||
new NativeDisplayEventReceiver(env, receiverWeak, vsyncEventDataWeak, messageQueue,
|
||||
vsyncSource, eventRegistration, layerHandle);
|
||||
new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource,
|
||||
eventRegistration, layerHandle);
|
||||
status_t status = receiver->initialize();
|
||||
if (status) {
|
||||
String8 message;
|
||||
@@ -329,9 +284,7 @@ static jobject nativeGetLatestVsyncEventData(JNIEnv* env, jclass clazz, jlong re
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
/* name, signature, funcPtr */
|
||||
{"nativeInit",
|
||||
"(Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;Landroid/os/"
|
||||
"MessageQueue;IIJ)J",
|
||||
{"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;IIJ)J",
|
||||
(void*)nativeInit},
|
||||
{"nativeGetDisplayEventReceiverFinalizer", "()J",
|
||||
(void*)nativeGetDisplayEventReceiverFinalizer},
|
||||
@@ -348,7 +301,8 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
|
||||
gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
|
||||
|
||||
gDisplayEventReceiverClassInfo.dispatchVsync =
|
||||
GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V");
|
||||
GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync",
|
||||
"(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V");
|
||||
gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
|
||||
gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
|
||||
gDisplayEventReceiverClassInfo.dispatchModeChanged =
|
||||
@@ -374,15 +328,6 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
|
||||
gDisplayEventReceiverClassInfo.frameTimelineClassInfo.init =
|
||||
GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz,
|
||||
"<init>", "(JJJ)V");
|
||||
gDisplayEventReceiverClassInfo.frameTimelineClassInfo.vsyncId =
|
||||
GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz,
|
||||
"vsyncId", "J");
|
||||
gDisplayEventReceiverClassInfo.frameTimelineClassInfo.expectedPresentationTime =
|
||||
GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz,
|
||||
"expectedPresentationTime", "J");
|
||||
gDisplayEventReceiverClassInfo.frameTimelineClassInfo.deadline =
|
||||
GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz,
|
||||
"deadline", "J");
|
||||
|
||||
jclass vsyncEventDataClazz =
|
||||
FindClassOrDie(env, "android/view/DisplayEventReceiver$VsyncEventData");
|
||||
@@ -394,17 +339,6 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
|
||||
"([Landroid/view/"
|
||||
"DisplayEventReceiver$VsyncEventData$FrameTimeline;IJ)V");
|
||||
|
||||
gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.preferredFrameTimelineIndex =
|
||||
GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz,
|
||||
"preferredFrameTimelineIndex", "I");
|
||||
gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameInterval =
|
||||
GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz,
|
||||
"frameInterval", "J");
|
||||
gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameTimelines =
|
||||
GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz,
|
||||
"frameTimelines",
|
||||
"[Landroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user