refresh.c revision b0878e4f2cef2275815bc4b1bcc2eaf68f439a51
1e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdio.h>
2e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h>
3e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <string.h>
4e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdint.h>
5e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/types.h>
6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <unistd.h>
8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <fcntl.h>
9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <math.h>
10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <time.h>
11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <errno.h>
12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/resource.h>
14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/syscall.h>
15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <sys/mman.h>
16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <linux/fb.h>
18e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
19e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint64_t systemTime()
20e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
21e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    struct timespec t;
22e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    t.tv_sec = t.tv_nsec = 0;
23e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    clock_gettime(CLOCK_MONOTONIC, &t);
24e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return (int64_t)(t.tv_sec)*1000000000LL + t.tv_nsec;
25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char** argv)
28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char const * const device_template[] = {
30e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "/dev/graphics/fb%u",
31e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "/dev/fb%u",
32e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            0 };
33e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int fd = -1;
34e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int i=0;
35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int j=0;
36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    char name[64];
37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    while ((fd==-1) && device_template[i]) {
38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        snprintf(name, 64, device_template[i], 0);
39e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        fd = open(name, O_RDWR, 0);
40e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        i++;
41e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (fd < 0)
43e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -errno;
44e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
45e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    struct fb_fix_screeninfo finfo;
46e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
47e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -errno;
48e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
49e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    struct fb_var_screeninfo info;
50e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
51e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -errno;
52e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
53e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.reserved[0] = 0;
54e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.reserved[1] = 0;
55e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.reserved[2] = 0;
56e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.xoffset = 0;
57e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.yoffset = 0;
58e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.bits_per_pixel = 16;
59e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.activate = FB_ACTIVATE_NOW;
60e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
61e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
62e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        printf("FBIOPUT_VSCREENINFO failed (%d x %d)\n",
63e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.xres_virtual, info.yres_virtual);
64e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return 0;
65e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
66e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
67e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
68e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -errno;
69e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
70b0878e4f2cef2275815bc4b1bcc2eaf68f439a51Iain Merrick    uint64_t denominator = (uint64_t)( info.upper_margin + info.lower_margin + info.yres )
71b0878e4f2cef2275815bc4b1bcc2eaf68f439a51Iain Merrick                         * ( info.left_margin  + info.right_margin + info.xres )
72b0878e4f2cef2275815bc4b1bcc2eaf68f439a51Iain Merrick                         * info.pixclock;
73b0878e4f2cef2275815bc4b1bcc2eaf68f439a51Iain Merrick    int refreshRate = denominator ? (1000000000000000LLU / denominator) : 0;
74e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
75e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    float xdpi = (info.xres * 25.4f) / info.width;
76e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    float ydpi = (info.yres * 25.4f) / info.height;
77e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    float fps  = refreshRate / 1000.0f;
78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
79e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf( "using (fd=%d)\n"
80e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "id           = %s\n"
81e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "xres         = %d px\n"
82e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "yres         = %d px\n"
83e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "xres_virtual = %d px\n"
84e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "yres_virtual = %d px\n"
85e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "bpp          = %d\n"
86e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "r            = %2u:%u\n"
87e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "g            = %2u:%u\n"
88e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "b            = %2u:%u\n",
89e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                fd,
90e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                finfo.id,
91e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.xres,
92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.yres,
93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.xres_virtual,
94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.yres_virtual,
95e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.bits_per_pixel,
96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.red.offset, info.red.length,
97e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.green.offset, info.green.length,
98e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.blue.offset, info.blue.length
99e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        );
100e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf( "width        = %d mm (%f dpi)\n"
102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "height       = %d mm (%f dpi)\n"
103e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            "refresh rate = %.2f Hz\n",
104e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.width,  xdpi,
105e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                info.height, ydpi,
106e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project                fps
107e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        );
108e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    printf("upper_margin=%d, lower_margin=%d, left_margin=%d, right_margin=%d, pixclock=%d, finfo.smem_len=%d\n",
110e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            info.upper_margin, info.lower_margin, info.left_margin, info.right_margin, info.pixclock, finfo.smem_len);
111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
112e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -errno;
114e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
115e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (finfo.smem_len <= 0)
116e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -errno;
117e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
118e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    /*
119e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project     * Open and map the display.
120e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project     */
121e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
122e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    uint16_t* buffer  = (uint16_t*) mmap(
123e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            0, finfo.smem_len,
124e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            PROT_READ | PROT_WRITE,
125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            MAP_SHARED,
126e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            fd, 0);
127e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
128e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    if (buffer == MAP_FAILED)
129e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        return -errno;
130e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
131e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    // at least for now, always clear the fb
132e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memset(buffer, 0, finfo.smem_len);
133e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    memset(buffer, 0xff, 320*(info.yres_virtual/2)*2);
134e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
135e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int l,t,w,h;
136e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    l=0;
137e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    t=0;
138e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    w=320;
139e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    h=480;
140e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.reserved[0] = 0x54445055; // "UPDT";
141e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
142e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    info.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
143e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
144e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int err;
145e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int c = 0;
146e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    int64_t time = systemTime();
147e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    while (1) {
148e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
149e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        info.activate = FB_ACTIVATE_VBL;
150e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        info.yoffset = 0;
151e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        ioctl(fd, FBIOPUT_VSCREENINFO, &info);
152e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
153e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        info.activate = FB_ACTIVATE_VBL;
154e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        info.yoffset = info.yres_virtual/2;
155e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        err = ioctl(fd, FBIOPUT_VSCREENINFO, &info);
156e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
157e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        c+=2;
158e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        if (c==60*2) {
159e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            int64_t now = systemTime();
160e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            time = now - time;
161e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            printf("refresh rate = %f Hz\n", (c*1000000000.0 / (double)time));
162e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            c = 0;
163e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project            time = now;
164e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project        }
165e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    }
166e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project    return 0;
167e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
168