Merge changes from topic "revert-21939399-VADOELCPVG" into udc-dev
* changes: Revert^2 "Copy from DisplayEventReceiver.VsyncEventData" Revert^2 "Remove JNI per-frame allocations in Choreographer"
This commit is contained in:
@@ -195,7 +195,7 @@ public final class Choreographer {
|
||||
|
||||
private boolean mDebugPrintNextFrameTimeDelta;
|
||||
private int mFPSDivisor = 1;
|
||||
private DisplayEventReceiver.VsyncEventData mLastVsyncEventData =
|
||||
private final DisplayEventReceiver.VsyncEventData mLastVsyncEventData =
|
||||
new DisplayEventReceiver.VsyncEventData();
|
||||
private final FrameData mFrameData = new FrameData();
|
||||
|
||||
@@ -860,7 +860,7 @@ public final class Choreographer {
|
||||
mFrameScheduled = false;
|
||||
mLastFrameTimeNanos = frameTimeNanos;
|
||||
mLastFrameIntervalNanos = frameIntervalNanos;
|
||||
mLastVsyncEventData = vsyncEventData;
|
||||
mLastVsyncEventData.copyFrom(vsyncEventData);
|
||||
}
|
||||
|
||||
if (resynced && Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
|
||||
@@ -1262,7 +1262,7 @@ public final class Choreographer {
|
||||
private boolean mHavePendingVsync;
|
||||
private long mTimestampNanos;
|
||||
private int mFrame;
|
||||
private VsyncEventData mLastVsyncEventData = new VsyncEventData();
|
||||
private final VsyncEventData mLastVsyncEventData = new VsyncEventData();
|
||||
|
||||
FrameDisplayEventReceiver(Looper looper, int vsyncSource, long layerHandle) {
|
||||
super(looper, vsyncSource, /* eventRegistration */ 0, layerHandle);
|
||||
@@ -1302,7 +1302,7 @@ public final class Choreographer {
|
||||
|
||||
mTimestampNanos = timestampNanos;
|
||||
mFrame = frame;
|
||||
mLastVsyncEventData = vsyncEventData;
|
||||
mLastVsyncEventData.copyFrom(vsyncEventData);
|
||||
Message msg = Message.obtain(mHandler, this);
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
|
||||
|
||||
@@ -81,7 +81,10 @@ 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
|
||||
@@ -124,7 +127,9 @@ public abstract class DisplayEventReceiver {
|
||||
}
|
||||
|
||||
mMessageQueue = looper.getQueue();
|
||||
mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
|
||||
mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this),
|
||||
new WeakReference<VsyncEventData>(mVsyncEventData),
|
||||
mMessageQueue,
|
||||
vsyncSource, eventRegistration, layerHandle);
|
||||
mFreeNativeResources = sNativeAllocationRegistry.registerNativeAllocation(this,
|
||||
mReceiverPtr);
|
||||
@@ -147,9 +152,6 @@ 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
|
||||
@@ -157,22 +159,32 @@ 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 final long vsyncId;
|
||||
public long vsyncId = FrameInfo.INVALID_VSYNC_ID;
|
||||
|
||||
// The frame timestamp for when the frame is expected to be presented.
|
||||
public final long expectedPresentationTime;
|
||||
public long expectedPresentationTime = Long.MAX_VALUE;
|
||||
|
||||
// The frame deadline timestamp in {@link System#nanoTime()} timebase that it is
|
||||
// allotted for the frame to be completed.
|
||||
public final long deadline;
|
||||
public long deadline = Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,11 +192,18 @@ public abstract class DisplayEventReceiver {
|
||||
* {@link FrameInfo#VSYNC} to the current vsync in case Choreographer callback was heavily
|
||||
* delayed by the app.
|
||||
*/
|
||||
public final long frameInterval;
|
||||
public long frameInterval = -1;
|
||||
|
||||
public final FrameTimeline[] frameTimelines;
|
||||
|
||||
public final int preferredFrameTimelineIndex;
|
||||
public int preferredFrameTimelineIndex = 0;
|
||||
|
||||
VsyncEventData() {
|
||||
frameTimelines = new FrameTimeline[FRAME_TIMELINES_LENGTH];
|
||||
for (int i = 0; i < frameTimelines.length; i++) {
|
||||
frameTimelines[i] = new FrameTimeline();
|
||||
}
|
||||
}
|
||||
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
@@ -195,10 +214,12 @@ public abstract class DisplayEventReceiver {
|
||||
this.frameInterval = frameInterval;
|
||||
}
|
||||
|
||||
VsyncEventData() {
|
||||
this.frameInterval = -1;
|
||||
this.frameTimelines = INVALID_FRAME_TIMELINES;
|
||||
this.preferredFrameTimelineIndex = 0;
|
||||
void copyFrom(VsyncEventData other) {
|
||||
preferredFrameTimelineIndex = other.preferredFrameTimelineIndex;
|
||||
frameInterval = other.frameInterval;
|
||||
for (int i = 0; i < frameTimelines.length; i++) {
|
||||
frameTimelines[i].copyFrom(other.frameTimelines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public FrameTimeline preferredFrameTimeline() {
|
||||
@@ -304,9 +325,8 @@ public abstract class DisplayEventReceiver {
|
||||
|
||||
// Called from native code.
|
||||
@SuppressWarnings("unused")
|
||||
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame,
|
||||
VsyncEventData vsyncEventData) {
|
||||
onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData);
|
||||
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
|
||||
onVsync(timestampNanos, physicalDisplayId, frame, mVsyncEventData);
|
||||
}
|
||||
|
||||
// Called from native code.
|
||||
|
||||
@@ -48,12 +48,22 @@ 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;
|
||||
@@ -61,7 +71,7 @@ static struct {
|
||||
|
||||
class NativeDisplayEventReceiver : public DisplayEventDispatcher {
|
||||
public:
|
||||
NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
|
||||
NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, jobject vsyncEventDataWeak,
|
||||
const sp<MessageQueue>& messageQueue, jint vsyncSource,
|
||||
jint eventRegistration, jlong layerHandle);
|
||||
|
||||
@@ -72,6 +82,7 @@ protected:
|
||||
|
||||
private:
|
||||
jobject mReceiverWeakGlobal;
|
||||
jobject mVsyncEventDataWeakGlobal;
|
||||
sp<MessageQueue> mMessageQueue;
|
||||
|
||||
void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count,
|
||||
@@ -85,6 +96,7 @@ private:
|
||||
};
|
||||
|
||||
NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
|
||||
jobject vsyncEventDataWeak,
|
||||
const sp<MessageQueue>& messageQueue,
|
||||
jint vsyncSource, jint eventRegistration,
|
||||
jlong layerHandle)
|
||||
@@ -96,6 +108,7 @@ 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);
|
||||
}
|
||||
@@ -154,12 +167,43 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
|
||||
ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
|
||||
if (receiverObj.get()) {
|
||||
ScopedLocalRef<jobject> vsyncEventDataObj(env, GetReferent(env, mVsyncEventDataWeakGlobal));
|
||||
if (receiverObj.get() && vsyncEventDataObj.get()) {
|
||||
ALOGV("receiver %p ~ Invoking vsync handler.", this);
|
||||
|
||||
jobject javaVsyncEventData = createJavaVsyncEventData(env, vsyncEventData);
|
||||
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);
|
||||
}
|
||||
|
||||
env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,
|
||||
timestamp, displayId.value, count, javaVsyncEventData);
|
||||
timestamp, displayId.value, count);
|
||||
ALOGV("receiver %p ~ Returned from vsync handler.", this);
|
||||
}
|
||||
|
||||
@@ -227,8 +271,9 @@ void NativeDisplayEventReceiver::dispatchFrameRateOverrides(
|
||||
mMessageQueue->raiseAndClearException(env, "dispatchModeChanged");
|
||||
}
|
||||
|
||||
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj,
|
||||
jint vsyncSource, jint eventRegistration, jlong layerHandle) {
|
||||
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject vsyncEventDataWeak,
|
||||
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.");
|
||||
@@ -236,8 +281,8 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject
|
||||
}
|
||||
|
||||
sp<NativeDisplayEventReceiver> receiver =
|
||||
new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource,
|
||||
eventRegistration, layerHandle);
|
||||
new NativeDisplayEventReceiver(env, receiverWeak, vsyncEventDataWeak, messageQueue,
|
||||
vsyncSource, eventRegistration, layerHandle);
|
||||
status_t status = receiver->initialize();
|
||||
if (status) {
|
||||
String8 message;
|
||||
@@ -284,7 +329,9 @@ static jobject nativeGetLatestVsyncEventData(JNIEnv* env, jclass clazz, jlong re
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
/* name, signature, funcPtr */
|
||||
{"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;IIJ)J",
|
||||
{"nativeInit",
|
||||
"(Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;Landroid/os/"
|
||||
"MessageQueue;IIJ)J",
|
||||
(void*)nativeInit},
|
||||
{"nativeGetDisplayEventReceiverFinalizer", "()J",
|
||||
(void*)nativeGetDisplayEventReceiverFinalizer},
|
||||
@@ -301,8 +348,7 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
|
||||
gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
|
||||
|
||||
gDisplayEventReceiverClassInfo.dispatchVsync =
|
||||
GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync",
|
||||
"(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V");
|
||||
GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V");
|
||||
gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
|
||||
gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
|
||||
gDisplayEventReceiverClassInfo.dispatchModeChanged =
|
||||
@@ -328,6 +374,15 @@ 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");
|
||||
@@ -339,6 +394,17 @@ 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