/** * Prints ShutterLag trace results. */ void ShutterLag::snapshotTaken(struct timeval *ts) { if (gShutterLag.isRunning()) { LOGD("ShutterLag from takePicture() to shot taken:\t%lldms\n", (((nsecs_t(ts->tv_sec)*1000000LL + nsecs_t(ts->tv_usec)) - gShutterLag.mStartAt/1000)/1000)); } }
nsecs_t systemTime(int /*clock*/) { // Clock support varies widely across hosts. Mac OS doesn't support // posix clocks, older glibcs don't support CLOCK_BOOTTIME and Windows // is windows. struct timeval t; t.tv_sec = t.tv_usec = 0; gettimeofday(&t, nullptr); return nsecs_t(t.tv_sec)*1000000000LL + nsecs_t(t.tv_usec)*1000LL; }
nsecs_t Fence::getSignalTime() const { if (mFenceFd == -1) { return -1; } struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd); if (finfo == NULL) { ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd); return -1; } if (finfo->status != 1) { sync_fence_info_free(finfo); return INT64_MAX; } struct sync_pt_info* pinfo = NULL; uint64_t timestamp = 0; while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) { if (pinfo->timestamp_ns > timestamp) { timestamp = pinfo->timestamp_ns; } } sync_fence_info_free(finfo); return nsecs_t(timestamp); }
int SprdVsyncEvent::getVSyncPeriod() { struct fb_var_screeninfo info; if (ioctl(mFbFd, FBIOGET_VSCREENINFO, &info) == -1) { return -errno; } int refreshRate = 0; if ( info.pixclock > 0 ) { refreshRate = 1000000000000000LLU / ( uint64_t(info.upper_margin + info.lower_margin + info.yres) * (info.left_margin + info.right_margin + info.xres) * info.pixclock); } else { ALOGW( "fbdev pixclock is zero for fd: %d", mFbFd ); } if (refreshRate == 0) { ALOGW("getVsyncPeriod refreshRate use fake rate, 60HZ"); refreshRate = 60*1000; // 60 Hz } float fps = refreshRate / 1000.0f; mVSyncPeriod = nsecs_t(1e9 / fps); return 0; }
// 20120814: add property function for debug purpose void HWComposer::VSyncThread::setProperty() { char value[PROPERTY_VALUE_MAX]; property_get("debug.sf.sw_vsync_fps", value, "0"); int fps = atoi(value); if (fps > 0) { mRefreshPeriod = nsecs_t(1e9 / fps); XLOGD("[VSYNC] set sw vsync fps(%d), period(%" PRId64 ")", fps, mRefreshPeriod); } }
/** * override for IAtomIspObserver::atomIspNotify() * * signal start of 3A processing based on 3A statistics available event * store SOF event information for future use */ bool AAAThread::atomIspNotify(IAtomIspObserver::Message *msg, const ObserverState state) { if(msg && msg->id == IAtomIspObserver::MESSAGE_ID_EVENT) { if (mSensorEmbeddedMetaDataEnabled || msg->data.event.type == EVENT_TYPE_METADATA_READY) { mSensorEmbeddedMetaDataEnabled = true; // When both sensor metadata event and statistics event are ready, then triggers 3A run if (msg->data.event.type == EVENT_TYPE_METADATA_READY) { mTrigger3A |= EVENT_TYPE_METADATA_READY; if (mTrigger3A & EVENT_TYPE_STATISTICS_READY) { mTrigger3A = 0; newStats(mCachedStatsEventMsg.data.event.timestamp, mCachedStatsEventMsg.data.event.sequence); CLEAR(mCachedStatsEventMsg); } return NO_ERROR; } if (msg->data.event.type == EVENT_TYPE_STATISTICS_READY) { mTrigger3A |= EVENT_TYPE_STATISTICS_READY; if (mTrigger3A & EVENT_TYPE_METADATA_READY) { mTrigger3A = 0; newStats(msg->data.event.timestamp, msg->data.event.sequence); } else { mCachedStatsEventMsg = *msg; } return NO_ERROR; } } else if (msg->data.event.type == EVENT_TYPE_STATISTICS_READY) { LOG2("-- STATS READY, seq %d, ts %lldus, systemTime %lldms ---", msg->data.event.sequence, nsecs_t(msg->data.event.timestamp.tv_sec)*1000000LL + nsecs_t(msg->data.event.timestamp.tv_usec), systemTime()/1000/1000); newStats(msg->data.event.timestamp, msg->data.event.sequence); } } else if (msg && msg->id == IAtomIspObserver::MESSAGE_ID_FRAME) { LOG2("--- FRAME, seq %d, ts %lldms, systemTime %lldms ---", msg->data.frameBuffer.buff.frameSequenceNbr, nsecs_t(msg->data.frameBuffer.buff.capture_timestamp.tv_sec)*1000000LL + nsecs_t(msg->data.frameBuffer.buff.capture_timestamp.tv_usec), systemTime()/1000/1000); newFrame(&msg->data.frameBuffer.buff); } return false; }
nsecs_t systemTime(int clock) { static const clockid_t clocks[] = { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID, CLOCK_BOOTTIME }; struct timespec t; t.tv_sec = t.tv_nsec = 0; clock_gettime(clocks[clock], &t); return nsecs_t(t.tv_sec)*1000000000LL + t.tv_nsec; }
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { ALOG_ASSERT(bufferSize >= 1); AutoMutex _l(mLock); struct input_event readBuffer[bufferSize]; RawEvent* event = buffer; size_t capacity = bufferSize; bool awoken = false; for (;;) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); // Reopen input devices if needed. if (mNeedToReopenDevices) { mNeedToReopenDevices = false; LOGI("Reopening all input devices due to a configuration change."); closeAllDevicesLocked(); mNeedToScanDevices = true; break; // return to the caller before we actually rescan } // Report any devices that had last been added/removed. while (mClosingDevices) { Device* device = mClosingDevices; ALOGV("Reporting device closed: id=%d, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; event->when = now; event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; event->type = DEVICE_REMOVED; event += 1; delete device; mNeedToSendFinishedDeviceScan = true; if (--capacity == 0) { break; } } if (mNeedToScanDevices) { mNeedToScanDevices = false; scanDevicesLocked(); mNeedToSendFinishedDeviceScan = true; } while (mOpeningDevices != NULL) { Device* device = mOpeningDevices; ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; event->when = now; event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; event->type = DEVICE_ADDED; event += 1; mNeedToSendFinishedDeviceScan = true; if (--capacity == 0) { break; } } if (mNeedToSendFinishedDeviceScan) { mNeedToSendFinishedDeviceScan = false; event->when = now; event->type = FINISHED_DEVICE_SCAN; event += 1; if (--capacity == 0) { break; } } // Grab the next input event. bool deviceChanged = false; while (mPendingEventIndex < mPendingEventCount) { const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++]; if (eventItem.data.u32 == EPOLL_ID_INOTIFY) { if (eventItem.events & EPOLLIN) { mPendingINotify = true; } else { ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events); } continue; } if (eventItem.data.u32 == EPOLL_ID_WAKE) { if (eventItem.events & EPOLLIN) { ALOGV("awoken after wake()"); awoken = true; char buffer[16]; ssize_t nRead; do { nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); } else { ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.", eventItem.events); } continue; } ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32); if (deviceIndex < 0) { ALOGW("Received unexpected epoll event 0x%08x for unknown device id %d.", eventItem.events, eventItem.data.u32); continue; } Device* device = mDevices.valueAt(deviceIndex); if (eventItem.events & EPOLLIN) { int32_t readSize = read(device->fd, readBuffer, sizeof(struct input_event) * capacity); if (readSize == 0 || (readSize < 0 && errno == ENODEV)) { // Device was removed before INotify noticed. ALOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d capacity: %d errno: %d)\n", device->fd, readSize, bufferSize, capacity, errno); deviceChanged = true; closeDeviceLocked(device); } else if (readSize < 0) { if (errno != EAGAIN && errno != EINTR) { ALOGW("could not get event (errno=%d)", errno); } } else if ((readSize % sizeof(struct input_event)) != 0) { LOGE("could not get event (wrong size: %d)", readSize); } else { int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; size_t count = size_t(readSize) / sizeof(struct input_event); for (size_t i = 0; i < count; i++) { const struct input_event& iev = readBuffer[i]; ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d", device->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); #ifdef HAVE_POSIX_CLOCKS // Use the time specified in the event instead of the current time // so that downstream code can get more accurate estimates of // event dispatch latency from the time the event is enqueued onto // the evdev client buffer. // // The event's timestamp fortuitously uses the same monotonic clock // time base as the rest of Android. The kernel event device driver // (drivers/input/evdev.c) obtains timestamps using ktime_get_ts(). // The systemTime(SYSTEM_TIME_MONOTONIC) function we use everywhere // calls clock_gettime(CLOCK_MONOTONIC) which is implemented as a // system call that also queries ktime_get_ts(). event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL + nsecs_t(iev.time.tv_usec) * 1000LL; ALOGV("event time %lld, now %lld", event->when, now); #else event->when = now; #endif event->deviceId = deviceId; event->type = iev.type; event->scanCode = iev.code; event->value = iev.value; event->keyCode = AKEYCODE_UNKNOWN; event->flags = 0; if (iev.type == EV_KEY && device->keyMap.haveKeyLayout()) { status_t err = device->keyMap.keyLayoutMap->mapKey(iev.code, &event->keyCode, &event->flags); ALOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n", iev.code, event->keyCode, event->flags, err); } event += 1; } capacity -= count; if (capacity == 0) { // The result buffer is full. Reset the pending event index // so we will try to read the device again on the next iteration. mPendingEventIndex -= 1; break; } } } else { ALOGW("Received unexpected epoll event 0x%08x for device %s.", eventItem.events, device->identifier.name.string()); } } // readNotify() will modify the list of devices so this must be done after // processing all other events to ensure that we read all remaining events // before closing the devices. if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) { mPendingINotify = false; readNotifyLocked(); deviceChanged = true; } // Report added or removed devices immediately. if (deviceChanged) { continue; } // Return now if we have collected any events or if we were explicitly awoken. if (event != buffer || awoken) { break; } // Poll for events. Mind the wake lock dance! // We hold a wake lock at all times except during epoll_wait(). This works due to some // subtle choreography. When a device driver has pending (unread) events, it acquires // a kernel wake lock. However, once the last pending event has been read, the device // driver will release the kernel wake lock. To prevent the system from going to sleep // when this happens, the EventHub holds onto its own user wake lock while the client // is processing events. Thus the system can only sleep if there are no events // pending or currently being processed. // // The timeout is advisory only. If the device is asleep, it will not wake just to // service the timeout. mPendingEventIndex = 0; mLock.unlock(); // release lock before poll, must be before release_wake_lock release_wake_lock(WAKE_LOCK_ID); int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); mLock.lock(); // reacquire lock after poll, must be after acquire_wake_lock if (pollResult == 0) { // Timed out. mPendingEventCount = 0; break; } if (pollResult < 0) { // An error occurred. mPendingEventCount = 0; // Sleep after errors to avoid locking up the system. // Hopefully the error is transient. if (errno != EINTR) { ALOGW("poll failed (errno=%d)\n", errno); usleep(100000); } } else { // Some events occurred. mPendingEventCount = size_t(pollResult); // On an SMP system, it is possible for the framework to read input events // faster than the kernel input device driver can produce a complete packet. // Because poll() wakes up as soon as the first input event becomes available, // the framework will often end up reading one event at a time until the // packet is complete. Instead of one call to read() returning 71 events, // it could take 71 calls to read() each returning 1 event. // // Sleep for a short period of time after waking up from the poll() to give // the kernel time to finish writing the entire packet of input events. if (mNumCpus > 1) { usleep(250); } } } // All done, return the number of events we read. return event - buffer; }
IntelFakeVsyncEvent::IntelFakeVsyncEvent(IntelHWComposer *hwc) : mEnabled(false), mComposer(hwc), mNextFakeVSync(0) { LOGV("Fake vsync event created"); mRefreshPeriod = nsecs_t(1e9 / 60); }
size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { LOG_ASSERT(bufferSize >= 1); AutoMutex _l(mLock); struct input_event readBuffer[bufferSize]; RawEvent* event = buffer; size_t capacity = bufferSize; bool awoken = false; for (;;) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); // Reopen input devices if needed. if (mNeedToReopenDevices) { mNeedToReopenDevices = false; LOGI("Reopening all input devices due to a configuration change."); closeAllDevicesLocked(); mNeedToScanDevices = true; break; // return to the caller before we actually rescan } // Report any devices that had last been added/removed. while (mClosingDevices) { Device* device = mClosingDevices; LOGV("Reporting device closed: id=%d, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; event->when = now; event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; event->type = DEVICE_REMOVED; event += 1; delete device; mNeedToSendFinishedDeviceScan = true; if (--capacity == 0) { break; } } if (mNeedToScanDevices) { mNeedToScanDevices = false; scanDevicesLocked(); mNeedToSendFinishedDeviceScan = true; } while (mOpeningDevices != NULL) { Device* device = mOpeningDevices; LOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; event->when = now; event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; event->type = DEVICE_ADDED; event += 1; mNeedToSendFinishedDeviceScan = true; if (--capacity == 0) { break; } } if (mNeedToSendFinishedDeviceScan) { mNeedToSendFinishedDeviceScan = false; event->when = now; event->type = FINISHED_DEVICE_SCAN; event += 1; if (--capacity == 0) { break; } } // Grab the next input event. bool deviceChanged = false; while (mPendingEventIndex < mPendingEventCount) { const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++]; if (eventItem.data.u32 == EPOLL_ID_INOTIFY) { if (eventItem.events & EPOLLIN) { mPendingINotify = true; } else { LOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events); } continue; } if (eventItem.data.u32 == EPOLL_ID_WAKE) { if (eventItem.events & EPOLLIN) { LOGV("awoken after wake()"); awoken = true; char buffer[16]; ssize_t nRead; do { nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); } else { LOGW("Received unexpected epoll event 0x%08x for wake read pipe.", eventItem.events); } continue; } ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32); if (deviceIndex < 0) { LOGW("Received unexpected epoll event 0x%08x for unknown device id %d.", eventItem.events, eventItem.data.u32); continue; } Device* device = mDevices.valueAt(deviceIndex); if (eventItem.events & EPOLLIN) { int32_t readSize = read(device->fd, readBuffer, sizeof(struct input_event) * capacity); if (readSize == 0 || (readSize < 0 && errno == ENODEV)) { // Device was removed before INotify noticed. LOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d capacity: %d errno: %d)\n", device->fd, readSize, bufferSize, capacity, errno); deviceChanged = true; closeDeviceLocked(device); } else if (readSize < 0) { if (errno != EAGAIN && errno != EINTR) { LOGW("could not get event (errno=%d)", errno); } } else if ((readSize % sizeof(struct input_event)) != 0) { LOGE("could not get event (wrong size: %d)", readSize); } else { int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id; size_t count = size_t(readSize) / sizeof(struct input_event); for (size_t i = 0; i < count; i++) { const struct input_event& iev = readBuffer[i]; LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d", device->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); /* add by ireadygo */ if(much_eventEnable(event, device->path.string()) == 0){ event += 1; continue; } #ifdef HAVE_POSIX_CLOCKS // Use the time specified in the event instead of the current time // so that downstream code can get more accurate estimates of // event dispatch latency from the time the event is enqueued onto // the evdev client buffer. // // The event's timestamp fortuitously uses the same monotonic clock // time base as the rest of Android. The kernel event device driver // (drivers/input/evdev.c) obtains timestamps using ktime_get_ts(). // The systemTime(SYSTEM_TIME_MONOTONIC) function we use everywhere // calls clock_gettime(CLOCK_MONOTONIC) which is implemented as a // system call that also queries ktime_get_ts(). event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL + nsecs_t(iev.time.tv_usec) * 1000LL; LOGV("event time %lld, now %lld", event->when, now); #else event->when = now; #endif //added by zhong about diandu //if(iev.type == EV_ABS) if(iev.type == EV_POINTERREADER) { event->deviceId = deviceId; event->flags = 0X1000; event->type =EV_KEY; event->keyCode = 0X1000; event->keyCode |=(iev.value&0XFF00000)>>4; event->scanCode = iev.code; event->scanCode |=(iev.value&0XFFFF0)<<12; event->value = iev.value & 0XF000000F; } else { event->deviceId = deviceId; event->type = iev.type; event->scanCode = iev.code; event->value = iev.value; event->keyCode = AKEYCODE_UNKNOWN; event->flags = 0; } //added by zhong about diandu if (iev.type == EV_KEY && device->keyMap.haveKeyLayout()) { status_t err = device->keyMap.keyLayoutMap->mapKey(iev.code, &event->keyCode, &event->flags); LOGE("iev.code=%d keyCode=%d flags=0x%08x err=%d\n", iev.code, event->keyCode, event->flags, err); } event += 1; } capacity -= count; if (capacity == 0) { // The result buffer is full. Reset the pending event index // so we will try to read the device again on the next iteration. mPendingEventIndex -= 1; break; } } } else {