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