107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/*
207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Copyright (C) 2010 The Android Open Source Project
307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Not a Contribution, Apache license notifications and license are
607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * retained for attribution purposes only.
707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Licensed under the Apache License, Version 2.0 (the "License");
907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * you may not use this file except in compliance with the License.
1007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * You may obtain a copy of the License at
1107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
1207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *      http://www.apache.org/licenses/LICENSE-2.0
1307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
1407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Unless required by applicable law or agreed to in writing, software
1507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * distributed under the License is distributed on an "AS IS" BASIS,
1607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * See the License for the specific language governing permissions and
1807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * limitations under the License.
1907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani */
2007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
2107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <cutils/properties.h>
2207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <utils/Log.h>
2307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <fcntl.h>
2407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <sys/ioctl.h>
2507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <linux/msm_mdp.h>
2607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <sys/resource.h>
2707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <sys/prctl.h>
2807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <poll.h>
2907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include "hwc_utils.h"
3007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include "hdmi.h"
3107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include "qd_utils.h"
3207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include "string.h"
3307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include "overlay.h"
3407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define __STDC_FORMAT_MACROS 1
3507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <inttypes.h>
3607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
3707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniusing namespace qdutils;
3807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaninamespace qhwc {
3907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
4007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define HWC_VSYNC_THREAD_NAME "hwcVsyncThread"
4107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define PANEL_ON_STR "panel_power_on ="
4207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
4307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MAX_THERMAL_LEVEL 3
4407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniconst int MAX_DATA = 64;
4507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
4607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniint hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable)
4707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
4807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int ret = 0;
4907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!ctx->vstate.fakevsync &&
5007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL,
5107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani             &enable) < 0) {
5207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: vsync control failed. Dpy=%d, enable=%d : %s",
5307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani              __FUNCTION__, dpy, enable, strerror(errno));
5407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ret = -errno;
5507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
5607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return ret;
5707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
5807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
5907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void handle_vsync_event(hwc_context_t* ctx, int dpy, char *data)
6007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
6107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // extract timestamp
6207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint64_t timestamp = 0;
6307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) {
6407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        timestamp = strtoull(data + strlen("VSYNC="), NULL, 0);
6507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
6607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // send timestamp to SurfaceFlinger
6707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ALOGD_IF (ctx->vstate.debug, "%s: timestamp %" PRIu64 " sent to SF for dpy=%d",
6807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            __FUNCTION__, timestamp, dpy);
6907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->proc->vsync(ctx->proc, dpy, timestamp);
7007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
7107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
7207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void handle_blank_event(hwc_context_t* ctx, int dpy, char *data)
7307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
7407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!strncmp(data, PANEL_ON_STR, strlen(PANEL_ON_STR))) {
7507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        unsigned long int poweron = strtoul(data + strlen(PANEL_ON_STR), NULL, 0);
7607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGI("%s: dpy:%d panel power state: %ld", __FUNCTION__, dpy, poweron);
7707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (!ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
7807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->dpyAttr[dpy].isActive = poweron ? true: false;
7907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
8007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
8107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
8207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
8307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void handle_thermal_event(hwc_context_t* ctx, int dpy, char *data)
8407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
8507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // extract thermal level
8607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint64_t thermalLevel = 0;
8707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!strncmp(data, "thermal_level=", strlen("thermal_level="))) {
8807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        thermalLevel = strtoull(data + strlen("thermal_level="), NULL, 0);
8907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
9007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
9107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (thermalLevel >= MAX_THERMAL_LEVEL) {
9207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGD("%s: dpy:%d thermal_level=%" PRIu64 "",__FUNCTION__,dpy,thermalLevel);
9307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->mThermalBurstMode = true;
9407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else
9507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->mThermalBurstMode = false;
9607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
9707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
9807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistruct event {
9907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    const char* name;
10007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    void (*callback)(hwc_context_t* ctx, int dpy, char *data);
10107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
10207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
10307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistruct event event_list[] =  {
10407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    { "vsync_event", handle_vsync_event },
10507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    { "show_blank_event", handle_blank_event },
10607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    { "msm_fb_thermal_level", handle_thermal_event },
10707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
10807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
10907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define num_events ARRAY_LENGTH(event_list)
11007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
11107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void *vsync_loop(void *param)
11207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
11307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param);
11407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
11507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    char thread_name[64] = HWC_VSYNC_THREAD_NAME;
11607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
11707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY +
11807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                android::PRIORITY_MORE_FAVORABLE);
11907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
12007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    char vdata[MAX_DATA];
12107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //Number of physical displays
12207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    //We poll on all the nodes.
12307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int num_displays = HWC_NUM_DISPLAY_TYPES - 1;
12407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct pollfd pfd[num_displays][num_events];
12507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
12607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    char property[PROPERTY_VALUE_MAX];
12707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(property_get("debug.hwc.fakevsync", property, NULL) > 0) {
12807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(atoi(property) == 1)
12907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->vstate.fakevsync = true;
13007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
13107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
13207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    char node_path[MAX_SYSFS_FILE_PATH];
13307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
13407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
13507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        for(size_t ev = 0; ev < num_events; ev++) {
13607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            snprintf(node_path, sizeof(node_path),
13707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    "/sys/class/graphics/fb%d/%s",
13807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    dpy == HWC_DISPLAY_PRIMARY ? 0 :
13907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    overlay::Overlay::getInstance()->
14007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    getFbForDpy(HWC_DISPLAY_EXTERNAL),
14107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    event_list[ev].name);
14207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
14307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGI("%s: Reading event %zu for dpy %d from %s", __FUNCTION__,
14407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    ev, dpy, node_path);
14507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            pfd[dpy][ev].fd = open(node_path, O_RDONLY);
14607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
14707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (dpy == HWC_DISPLAY_PRIMARY && pfd[dpy][ev].fd < 0) {
14807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                // Make sure fb device is opened before starting
14907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                // this thread so this never happens.
15007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ALOGE ("%s:unable to open event node for dpy=%d event=%zu, %s",
15107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                        __FUNCTION__, dpy, ev, strerror(errno));
15207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                if (ev == 0) {
15307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    ctx->vstate.fakevsync = true;
15407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    //XXX: Blank events don't work with fake vsync,
15507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    //but we shouldn't be running on fake vsync anyway.
15607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    break;
15707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                }
15807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
15907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
16007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            memset(&vdata, '\0', sizeof(vdata));
16107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // Read once from the fds to clear the first notify
16207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            pread(pfd[dpy][ev].fd, vdata , MAX_DATA - 1, 0);
16307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (pfd[dpy][ev].fd >= 0)
16407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                pfd[dpy][ev].events = POLLPRI | POLLERR;
16507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
16607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
16707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
16807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (LIKELY(!ctx->vstate.fakevsync)) {
16907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        do {
17007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            int err = poll(*pfd, (int)(num_displays * num_events), -1);
17107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if(err > 0) {
17207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) {
17307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    for(size_t ev = 0; ev < num_events; ev++) {
17407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                        if (pfd[dpy][ev].revents & POLLPRI) {
17507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            // Clear vdata before writing into it
17607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            memset(&vdata, '\0', sizeof(vdata));
17707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            ssize_t len = pread(pfd[dpy][ev].fd, vdata,
17807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                MAX_DATA - 1, 0);
17907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            if (UNLIKELY(len < 0)) {
18007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                // If the read was just interrupted - it is not
18107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                // a fatal error. Just continue in this case
18207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                ALOGE ("%s: Unable to read event:%zu for \
18307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                        dpy=%d : %s",
18407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                        __FUNCTION__, ev, dpy, strerror(errno));
18507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                continue;
18607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            }
18707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            vdata[len] = '\0';
18807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            event_list[ev].callback(ctx, dpy, vdata);
18907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                        }
19007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    }
19107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                }
19207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } else {
19307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ALOGE("%s: poll failed errno: %s", __FUNCTION__,
19407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                        strerror(errno));
19507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                continue;
19607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
19707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } while (true);
19807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
19907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
20007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
20107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //Fake vsync is used only when set explicitly through a property or when
20207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //the vsync timestamp node cannot be opened at bootup. There is no
20307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //fallback to fake vsync from the true vsync loop, ever, as the
20407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //condition can easily escape detection.
20507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //Also, fake vsync is delivered only for the primary display.
20607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        do {
20707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            usleep(16666);
20807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            uint64_t timestamp = systemTime();
20907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, timestamp);
21007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
21107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } while (true);
21207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
21307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
21407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int dpy = HWC_DISPLAY_PRIMARY; dpy <= HWC_DISPLAY_EXTERNAL; dpy++ ) {
21507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        for( size_t event = 0; event < num_events; event++) {
21607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if(pfd[dpy][event].fd >= 0)
21707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                close (pfd[dpy][event].fd);
21807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
21907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
22007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
22107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return NULL;
22207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
22307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
22407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanivoid init_vsync_thread(hwc_context_t* ctx)
22507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
22607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int ret;
22707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_t vsync_thread;
22807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ALOGI("Initializing VSYNC Thread");
22907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx);
23007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (ret) {
23107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: failed to create %s: %s", __FUNCTION__,
23207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani              HWC_VSYNC_THREAD_NAME, strerror(ret));
23307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
23407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
23507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
23607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}; //namespace
237