-
Notifications
You must be signed in to change notification settings - Fork 4
/
rk_hwcomposer_htg.cpp
133 lines (115 loc) · 3.1 KB
/
rk_hwcomposer_htg.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* rockchip hwcomposer( 2D graphic acceleration unit) .
*
* Copyright (C) 2015 Rockchip Electronics Co., Ltd.
*/
#include <sys/prctl.h>
#include "rk_hwcomposer_hdmi.h"
#include <errno.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <cutils/log.h>
#include <cutils/properties.h>
#include <hardware_legacy/uevent.h>
#include <string.h>
int g_hdmi_mode;
int mUsedVopNum;
int rk_parse_uevent_buf(const char *buf,int* type,int* flag,int* fbx, int* vopId, int len)
{
int ret = -1;
const char *str = buf;
//ALOGD("[%s]",buf);
while(*str) {
if(!strcmp(str,"switch screen")) ret = 1;
sscanf(str,"SCREEN=%d,ENABLE=%d",type,flag);
sscanf(str,"FBDEV=%d",fbx);
if(ret==1) ALOGI("SCREEN=%d ENABLE=%d,vopId=%d",*type,*flag,*vopId);
str += strlen(str) + 1;
if (str - buf >= len){
break;
}
if(ret==1) ALOGI("line %d,buf[%s]",__LINE__,str);
}
return ret;
}
int rk_check_hdmi_state()
{
int ret = 0;
int fd = open("/sys/devices/virtual/display/HDMI/connect", O_RDONLY);
if (fd > 0) {
char statebuf[100];
memset(statebuf, 0, sizeof(statebuf));
int err = read(fd, statebuf, sizeof(statebuf));
if (err < 0) {
close(fd);
ALOGE("error reading hdmi state: %s", strerror(errno));
return -errno;
}
close(fd);
ret = atoi(statebuf);
ALOGI("Read HDMI connect state = %d");
} else {
ALOGD("err=%s",strerror(errno));
}
return ret;
}
void rk_check_hdmi_uevents(const char *buf,int len)
{
int ret = 0;
int vopId = -1;
int fbIndex = 0;
int screenType = 0;
int statusFlag = 0;
int hdmiStatus = -1;
ret = rk_parse_uevent_buf(buf,&screenType,&statusFlag,&fbIndex,&vopId,len);
if(ret != 1) return;
g_hdmi_mode = rk_check_hdmi_state();
if (screenType == -1 && statusFlag == -1)
handle_hotplug_event(-1, -1);
else if (fbIndex == 0)
hotplug_change_screen_config(0, fbIndex, statusFlag);
else
handle_hotplug_event(statusFlag, 0);
ALOGI("uevent receive!type=%d,status=%d,hdmi=%d,vop=%d,fb=%d,line=%d",
screenType, statusFlag, g_hdmi_mode, vopId, fbIndex, __LINE__);
return;
}
void rk_handle_uevents(const char *buff,int len)
{
// uint64_t timestamp = 0;
rk_check_hdmi_uevents(buff,len);
}
void *rk_hwc_hdmi_thread(void *arg)
{
prctl(PR_SET_NAME,"HWC_Uevent");
static char uevent_desc[4096];
struct pollfd fds[1];
int timeout;
int err;
uevent_init();
fds[0].fd = uevent_get_fd();
fds[0].events = POLLIN;
timeout = 200;//ms
memset(uevent_desc, 0, sizeof(uevent_desc));
do {
err = poll(fds, 1, timeout);
if (err == -1) {
if (errno != EINTR)
ALOGE("event error: %m");
continue;
}
if (fds[0].revents & POLLIN) {
int len = uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2);
rk_handle_uevents(uevent_desc,len);
}
} while (1);
pthread_exit(NULL);
return NULL;
}