diff options
Diffstat (limited to 'msm8909/libhwcomposer/hwc_vsync.cpp')
-rw-r--r-- | msm8909/libhwcomposer/hwc_vsync.cpp | 239 |
1 files changed, 0 insertions, 239 deletions
diff --git a/msm8909/libhwcomposer/hwc_vsync.cpp b/msm8909/libhwcomposer/hwc_vsync.cpp deleted file mode 100644 index ea3f672d..00000000 --- a/msm8909/libhwcomposer/hwc_vsync.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved. - * - * Not a Contribution, Apache license notifications and license are - * retained for attribution purposes only. - - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cutils/properties.h> -#include <utils/Log.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <linux/msm_mdp.h> -#include <sys/resource.h> -#include <sys/prctl.h> -#include <poll.h> -#include "hwc_utils.h" -#include "hdmi.h" -#include "qd_utils.h" -#include "string.h" -#include "overlay.h" -#include <inttypes.h> - -using namespace qdutils; -namespace qhwc { - -#define HWC_VSYNC_THREAD_NAME "hwcVsyncThread" -#define PANEL_ON_STR "panel_power_on =" -#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0])) -#define MAX_THERMAL_LEVEL 3 -const int MAX_DATA = 64; - -int hwc_vsync_control(hwc_context_t* ctx, int dpy, int enable) -{ - int ret = 0; - if(!ctx->vstate.fakevsync && - ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL, - &enable) < 0) { - ALOGE("%s: vsync control failed. Dpy=%d, enable=%d : %s", - __FUNCTION__, dpy, enable, strerror(errno)); - ret = -errno; - } - return ret; -} - -static void handle_vsync_event(hwc_context_t* ctx, int dpy, char *data) -{ - // extract timestamp - uint64_t timestamp = 0; - if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) { - timestamp = strtoull(data + strlen("VSYNC="), NULL, 0); - } - // send timestamp to SurfaceFlinger - ALOGD_IF (ctx->vstate.debug, "%s: timestamp %" PRIu64 " sent to SF for dpy=%d", - __FUNCTION__, timestamp, dpy); - ctx->proc->vsync(ctx->proc, dpy, timestamp); -} - -static void handle_blank_event(hwc_context_t* ctx, int dpy, char *data) -{ - if (!strncmp(data, PANEL_ON_STR, strlen(PANEL_ON_STR))) { - unsigned long int poweron = strtoul(data + strlen(PANEL_ON_STR), NULL, 0); - ALOGI("%s: dpy:%d panel power state: %ld", __FUNCTION__, dpy, poweron); - if (!ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) { - ctx->dpyAttr[dpy].isActive = poweron ? true: false; - } - } -} - -static void handle_thermal_event(hwc_context_t* ctx, int dpy, char *data) -{ - // extract thermal level - uint64_t thermalLevel = 0; - if (!strncmp(data, "thermal_level=", strlen("thermal_level="))) { - thermalLevel = strtoull(data + strlen("thermal_level="), NULL, 0); - } - - if (thermalLevel >= MAX_THERMAL_LEVEL) { - ALOGD("%s: dpy:%d thermal_level=%" PRIu64 "",__FUNCTION__,dpy,thermalLevel); - ctx->mThermalBurstMode = true; - } else - ctx->mThermalBurstMode = false; -} - -struct event { - const char* name; - void (*callback)(hwc_context_t* ctx, int dpy, char *data); -}; - -struct event event_list[] = { - { "vsync_event", handle_vsync_event }, - { "show_blank_event", handle_blank_event }, - { "msm_fb_thermal_level", handle_thermal_event }, -}; - -#define num_events ARRAY_LENGTH(event_list) - -static void *vsync_loop(void *param) -{ - hwc_context_t * ctx = reinterpret_cast<hwc_context_t *>(param); - - char thread_name[64] = HWC_VSYNC_THREAD_NAME; - prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0); - struct sched_param sched_param = {0}; - sched_param.sched_priority = 5; - if (sched_setscheduler(gettid(), SCHED_FIFO, &sched_param) != 0) { - ALOGE("Couldn't set SCHED_FIFO for hwc_vsync"); - } - - char vdata[MAX_DATA]; - //Number of physical displays - //We poll on all the nodes. - int num_displays = HWC_NUM_DISPLAY_TYPES - 1; - struct pollfd pfd[num_displays][num_events]; - - char property[PROPERTY_VALUE_MAX]; - if(property_get("debug.hwc.fakevsync", property, NULL) > 0) { - if(atoi(property) == 1) - ctx->vstate.fakevsync = true; - } - - char node_path[MAX_SYSFS_FILE_PATH]; - - for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) { - for(size_t ev = 0; ev < num_events; ev++) { - snprintf(node_path, sizeof(node_path), - "/sys/class/graphics/fb%d/%s", - dpy == HWC_DISPLAY_PRIMARY ? 0 : - overlay::Overlay::getInstance()-> - getFbForDpy(HWC_DISPLAY_EXTERNAL), - event_list[ev].name); - - ALOGI("%s: Reading event %zu for dpy %d from %s", __FUNCTION__, - ev, dpy, node_path); - pfd[dpy][ev].fd = open(node_path, O_RDONLY); - - if (dpy == HWC_DISPLAY_PRIMARY && pfd[dpy][ev].fd < 0) { - // Make sure fb device is opened before starting - // this thread so this never happens. - ALOGE ("%s:unable to open event node for dpy=%d event=%zu, %s", - __FUNCTION__, dpy, ev, strerror(errno)); - if (ev == 0) { - ctx->vstate.fakevsync = true; - //XXX: Blank events don't work with fake vsync, - //but we shouldn't be running on fake vsync anyway. - break; - } - } - - memset(&vdata, '\0', sizeof(vdata)); - // Read once from the fds to clear the first notify - pread(pfd[dpy][ev].fd, vdata , MAX_DATA - 1, 0); - if (pfd[dpy][ev].fd >= 0) - pfd[dpy][ev].events = POLLPRI | POLLERR; - } - } - - if (LIKELY(!ctx->vstate.fakevsync)) { - do { - int err = poll(reinterpret_cast<struct pollfd *>(pfd), - (int)(num_displays * num_events), -1); - if(err > 0) { - for (int dpy = HWC_DISPLAY_PRIMARY; dpy < num_displays; dpy++) { - for(size_t ev = 0; ev < num_events; ev++) { - if (pfd[dpy][ev].revents & POLLPRI) { - // Clear vdata before writing into it - memset(&vdata, '\0', sizeof(vdata)); - ssize_t len = pread(pfd[dpy][ev].fd, vdata, - MAX_DATA - 1, 0); - if (UNLIKELY(len < 0)) { - // If the read was just interrupted - it is not - // a fatal error. Just continue in this case - ALOGE ("%s: Unable to read event:%zu for \ - dpy=%d : %s", - __FUNCTION__, ev, dpy, strerror(errno)); - continue; - } - vdata[len] = '\0'; - event_list[ev].callback(ctx, dpy, vdata); - } - } - } - } else { - ALOGE("%s: poll failed errno: %s", __FUNCTION__, - strerror(errno)); - continue; - } - } while (true); - - } else { - - //Fake vsync is used only when set explicitly through a property or when - //the vsync timestamp node cannot be opened at bootup. There is no - //fallback to fake vsync from the true vsync loop, ever, as the - //condition can easily escape detection. - //Also, fake vsync is delivered only for the primary display. - do { - usleep(16666); - uint64_t timestamp = systemTime(); - ctx->proc->vsync(ctx->proc, HWC_DISPLAY_PRIMARY, timestamp); - - } while (true); - } - - for (int dpy = HWC_DISPLAY_PRIMARY; dpy <= HWC_DISPLAY_EXTERNAL; dpy++ ) { - for( size_t event = 0; event < num_events; event++) { - if(pfd[dpy][event].fd >= 0) - close (pfd[dpy][event].fd); - } - } - - return NULL; -} - -void init_vsync_thread(hwc_context_t* ctx) -{ - int ret; - pthread_t vsync_thread; - ALOGI("Initializing VSYNC Thread"); - ret = pthread_create(&vsync_thread, NULL, vsync_loop, (void*) ctx); - if (ret) { - ALOGE("%s: failed to create %s: %s", __FUNCTION__, - HWC_VSYNC_THREAD_NAME, strerror(ret)); - } -} - -}; //namespace |