summaryrefslogtreecommitdiff
path: root/msm8909/libhwcomposer/hwc_vsync.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'msm8909/libhwcomposer/hwc_vsync.cpp')
-rw-r--r--msm8909/libhwcomposer/hwc_vsync.cpp239
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