Loading libs/gui/DisplayEventDispatcher.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -73,7 +73,8 @@ status_t DisplayEventDispatcher::scheduleVsync() { nsecs_t vsyncTimestamp; PhysicalDisplayId vsyncDisplayId; uint32_t vsyncCount; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { int64_t vsyncId; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncId)) { ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "", this, ns2ms(static_cast<nsecs_t>(vsyncTimestamp))); } Loading Loading @@ -116,11 +117,13 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) { nsecs_t vsyncTimestamp; PhysicalDisplayId vsyncDisplayId; uint32_t vsyncCount; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%s, count=%d", this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount); int64_t vsyncId; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncId)) { ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%s, count=%d, vsyncId=%" PRId64, this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount, vsyncId); mWaitingForVsync = false; dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount); dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncId); } return 1; // keep the callback Loading @@ -128,10 +131,11 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) { bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, uint32_t* outCount) { uint32_t* outCount, int64_t* outVsyncId) { bool gotVsync = false; DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE]; ssize_t n; *outVsyncId = 0; while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) { ALOGV("dispatcher %p ~ Read %d events.", this, int(n)); for (ssize_t i = 0; i < n; i++) { Loading @@ -144,6 +148,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, *outTimestamp = ev.header.timestamp; *outDisplayId = ev.header.displayId; *outCount = ev.vsync.count; *outVsyncId = ev.vsync.vsyncId; break; case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected); Loading libs/gui/ISurfaceComposer.cpp +59 −0 Original line number Diff line number Diff line Loading @@ -1165,6 +1165,38 @@ public: return NO_ERROR; } virtual status_t setFrameTimelineVsync(const sp<IGraphicBufferProducer>& surface, int64_t frameTimelineVsyncId) { Parcel data, reply; status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed writing interface token: %s (%d)", strerror(-err), -err); return err; } err = data.writeStrongBinder(IInterface::asBinder(surface)); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed writing strong binder: %s (%d)", strerror(-err), -err); return err; } err = data.writeInt64(frameTimelineVsyncId); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed writing int64_t: %s (%d)", strerror(-err), -err); return err; } err = remote()->transact(BnSurfaceComposer::SET_FRAME_TIMELINE_VSYNC, data, &reply); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed to transact: %s (%d)", strerror(-err), err); return err; } return reply.readInt32(); } }; // Out-of-line virtual method definition to trigger vtable emission in this Loading Loading @@ -1967,6 +1999,33 @@ status_t BnSurfaceComposer::onTransact( } return NO_ERROR; } case SET_FRAME_TIMELINE_VSYNC: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> binder; status_t err = data.readStrongBinder(&binder); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed to read strong binder: %s (%d)", strerror(-err), -err); return err; } sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(binder); if (!surface) { ALOGE("setFrameTimelineVsync: failed to cast to IGraphicBufferProducer: %s (%d)", strerror(-err), -err); return err; } int64_t frameTimelineVsyncId; err = data.readInt64(&frameTimelineVsyncId); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed to read int64_t: %s (%d)", strerror(-err), -err); return err; } status_t result = setFrameTimelineVsync(surface, frameTimelineVsyncId); reply->writeInt32(result); return NO_ERROR; } default: { return BBinder::onTransact(code, data, reply, flags); } Loading libs/gui/Surface.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -1207,6 +1207,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER: res = dispatchGetLastQueuedBuffer(args); break; case NATIVE_WINDOW_SET_FRAME_TIMELINE_VSYNC: res = dispatchSetFrameTimelineVsync(args); break; default: res = NAME_NOT_FOUND; break; Loading Loading @@ -1513,6 +1516,14 @@ int Surface::dispatchGetLastQueuedBuffer(va_list args) { return result; } int Surface::dispatchSetFrameTimelineVsync(va_list args) { ATRACE_CALL(); auto frameTimelineVsyncId = static_cast<int64_t>(va_arg(args, int64_t)); ALOGV("Surface::dispatchSetFrameTimelineVsync"); return composerService()->setFrameTimelineVsync(mGraphicBufferProducer, frameTimelineVsyncId); } bool Surface::transformToDisplayInverse() { return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; Loading libs/gui/include/gui/DisplayEventDispatcher.h +3 −2 Original line number Diff line number Diff line Loading @@ -43,7 +43,8 @@ private: DisplayEventReceiver mReceiver; bool mWaitingForVsync; virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) = 0; virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count, int64_t vsyncId) = 0; virtual void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) = 0; virtual void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId, Loading @@ -53,6 +54,6 @@ private: virtual void dispatchNullEvent(nsecs_t timestamp, PhysicalDisplayId displayId) = 0; bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, uint32_t* outCount); uint32_t* outCount, int64_t* outVsyncId); }; } // namespace android libs/gui/include/gui/DisplayEventReceiver.h +1 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ public: uint32_t count; nsecs_t expectedVSyncTimestamp __attribute__((aligned(8))); nsecs_t deadlineTimestamp __attribute__((aligned(8))); int64_t vsyncId; }; struct Hotplug { Loading Loading
libs/gui/DisplayEventDispatcher.cpp +11 −6 Original line number Diff line number Diff line Loading @@ -73,7 +73,8 @@ status_t DisplayEventDispatcher::scheduleVsync() { nsecs_t vsyncTimestamp; PhysicalDisplayId vsyncDisplayId; uint32_t vsyncCount; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { int64_t vsyncId; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncId)) { ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "", this, ns2ms(static_cast<nsecs_t>(vsyncTimestamp))); } Loading Loading @@ -116,11 +117,13 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) { nsecs_t vsyncTimestamp; PhysicalDisplayId vsyncDisplayId; uint32_t vsyncCount; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) { ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%s, count=%d", this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount); int64_t vsyncId; if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncId)) { ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%s, count=%d, vsyncId=%" PRId64, this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount, vsyncId); mWaitingForVsync = false; dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount); dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncId); } return 1; // keep the callback Loading @@ -128,10 +131,11 @@ int DisplayEventDispatcher::handleEvent(int, int events, void*) { bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, uint32_t* outCount) { uint32_t* outCount, int64_t* outVsyncId) { bool gotVsync = false; DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE]; ssize_t n; *outVsyncId = 0; while ((n = mReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) { ALOGV("dispatcher %p ~ Read %d events.", this, int(n)); for (ssize_t i = 0; i < n; i++) { Loading @@ -144,6 +148,7 @@ bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp, *outTimestamp = ev.header.timestamp; *outDisplayId = ev.header.displayId; *outCount = ev.vsync.count; *outVsyncId = ev.vsync.vsyncId; break; case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected); Loading
libs/gui/ISurfaceComposer.cpp +59 −0 Original line number Diff line number Diff line Loading @@ -1165,6 +1165,38 @@ public: return NO_ERROR; } virtual status_t setFrameTimelineVsync(const sp<IGraphicBufferProducer>& surface, int64_t frameTimelineVsyncId) { Parcel data, reply; status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed writing interface token: %s (%d)", strerror(-err), -err); return err; } err = data.writeStrongBinder(IInterface::asBinder(surface)); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed writing strong binder: %s (%d)", strerror(-err), -err); return err; } err = data.writeInt64(frameTimelineVsyncId); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed writing int64_t: %s (%d)", strerror(-err), -err); return err; } err = remote()->transact(BnSurfaceComposer::SET_FRAME_TIMELINE_VSYNC, data, &reply); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed to transact: %s (%d)", strerror(-err), err); return err; } return reply.readInt32(); } }; // Out-of-line virtual method definition to trigger vtable emission in this Loading Loading @@ -1967,6 +1999,33 @@ status_t BnSurfaceComposer::onTransact( } return NO_ERROR; } case SET_FRAME_TIMELINE_VSYNC: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IBinder> binder; status_t err = data.readStrongBinder(&binder); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed to read strong binder: %s (%d)", strerror(-err), -err); return err; } sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(binder); if (!surface) { ALOGE("setFrameTimelineVsync: failed to cast to IGraphicBufferProducer: %s (%d)", strerror(-err), -err); return err; } int64_t frameTimelineVsyncId; err = data.readInt64(&frameTimelineVsyncId); if (err != NO_ERROR) { ALOGE("setFrameTimelineVsync: failed to read int64_t: %s (%d)", strerror(-err), -err); return err; } status_t result = setFrameTimelineVsync(surface, frameTimelineVsyncId); reply->writeInt32(result); return NO_ERROR; } default: { return BBinder::onTransact(code, data, reply, flags); } Loading
libs/gui/Surface.cpp +11 −0 Original line number Diff line number Diff line Loading @@ -1207,6 +1207,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER: res = dispatchGetLastQueuedBuffer(args); break; case NATIVE_WINDOW_SET_FRAME_TIMELINE_VSYNC: res = dispatchSetFrameTimelineVsync(args); break; default: res = NAME_NOT_FOUND; break; Loading Loading @@ -1513,6 +1516,14 @@ int Surface::dispatchGetLastQueuedBuffer(va_list args) { return result; } int Surface::dispatchSetFrameTimelineVsync(va_list args) { ATRACE_CALL(); auto frameTimelineVsyncId = static_cast<int64_t>(va_arg(args, int64_t)); ALOGV("Surface::dispatchSetFrameTimelineVsync"); return composerService()->setFrameTimelineVsync(mGraphicBufferProducer, frameTimelineVsyncId); } bool Surface::transformToDisplayInverse() { return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; Loading
libs/gui/include/gui/DisplayEventDispatcher.h +3 −2 Original line number Diff line number Diff line Loading @@ -43,7 +43,8 @@ private: DisplayEventReceiver mReceiver; bool mWaitingForVsync; virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) = 0; virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count, int64_t vsyncId) = 0; virtual void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) = 0; virtual void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId, Loading @@ -53,6 +54,6 @@ private: virtual void dispatchNullEvent(nsecs_t timestamp, PhysicalDisplayId displayId) = 0; bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, uint32_t* outCount); uint32_t* outCount, int64_t* outVsyncId); }; } // namespace android
libs/gui/include/gui/DisplayEventReceiver.h +1 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,7 @@ public: uint32_t count; nsecs_t expectedVSyncTimestamp __attribute__((aligned(8))); nsecs_t deadlineTimestamp __attribute__((aligned(8))); int64_t vsyncId; }; struct Hotplug { Loading