Created
June 27, 2018 14:52
-
-
Save mosolovsa/3153b09b18e314281e95c510f84aa0de to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <assert.h> | |
#include <string.h> | |
#include <fcntl.h> | |
#include <malloc.h> | |
#include <math.h> | |
#include <stdlib.h> | |
//#define EGL_USE_GLES2 | |
#include <GLES2/gl2.h> | |
#include <EGL/egl.h> | |
#include <GLES2/gl2ext.h> | |
#include <EGL/eglext.h> | |
#include <termios.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#ifdef EGL_USE_X11 | |
#include <X11/X.h> | |
#include <X11/Xlib.h> | |
#endif | |
EGLDisplay egldisplay; | |
EGLConfig eglconfig; | |
EGLSurface eglsurface; | |
EGLContext eglcontext; | |
EGLNativeWindowType eglNativeWindow; | |
EGLNativeDisplayType eglNativeDisplayType; | |
EGLNativeDisplayType fsl_getNativeDisplay() | |
{ | |
EGLNativeDisplayType eglNativeDisplayType = NULL; | |
#if (defined EGL_USE_X11) | |
eglNativeDisplayType = XOpenDisplay(NULL); | |
assert(eglNativeDisplayType != NULL); | |
#elif (defined EGL_API_FB) | |
eglNativeDisplayType = fbGetDisplayByIndex(0); //Pass the argument as required to show the framebuffer | |
#else | |
display = EGL_DEFAULT_DISPLAY; | |
#endif | |
return eglNativeDisplayType; | |
} | |
EGLNativeWindowType fsl_createwindow(EGLDisplay egldisplay, EGLNativeDisplayType eglNativeDisplayType) | |
{ | |
EGLNativeWindowType native_window = (EGLNativeWindowType)0; | |
#if (defined EGL_USE_X11) | |
Window window, rootwindow; | |
int screen = DefaultScreen(eglNativeDisplayType); | |
rootwindow = RootWindow(eglNativeDisplayType,screen); | |
window = XCreateSimpleWindow(eglNativeDisplayType, rootwindow, 0, 0, 400, 533, 0, 0, WhitePixel (eglNativeDisplayType, screen)); | |
XMapWindow(eglNativeDisplayType, window); | |
native_window = window; | |
#else | |
const char *vendor = eglQueryString(egldisplay, EGL_VENDOR); | |
if (strstr(vendor, "Imagination Technologies")) { | |
printf("Imagination Technologies vendor [%s]\n", vendor); | |
native_window = (EGLNativeWindowType) 0; | |
} else if (strstr(vendor, "AMD")) { | |
printf("AMD vendor [%s]\n", vendor); | |
native_window = (EGLNativeWindowType) open("/dev/fb0", O_RDWR); | |
} else if (strstr(vendor, "Vivante")) //NEEDS FIX - functs don't exist on other platforms | |
{ | |
#if (defined EGL_API_FB) | |
printf("Vivante vendor [%s]\n", vendor); | |
native_window = fbCreateWindow(eglNativeDisplayType, 0, 0, 0, 0); | |
#endif | |
} | |
else | |
{ | |
printf("Unknown vendor [%s]\n", vendor); | |
return 0; | |
} | |
#endif | |
return native_window; | |
} | |
void fsl_destroywindow(EGLNativeWindowType eglNativeWindowType, EGLNativeDisplayType eglNativeDisplayType) | |
{ | |
(void) eglNativeWindowType; | |
#if (defined EGL_USE_X11) | |
//close x display | |
XCloseDisplay(eglNativeDisplayType); | |
#endif | |
} | |
void query(EGLint attr, char *attr_name) { | |
EGLBoolean result; | |
EGLint value; | |
result = eglQuerySurface(egldisplay, eglsurface, attr, &value); | |
if (result != EGL_TRUE) { | |
printf("\nERROR, result %d - %s: %d\n", result, attr_name, value); | |
} else { | |
printf("\nresult %d - %s: %d\n", result, attr_name, value); | |
} | |
fflush(stdout); | |
} | |
void queryAttr(EGLint attr, char *attr_name) { | |
EGLBoolean result; | |
EGLint value; | |
result = eglGetConfigAttrib(egldisplay, eglconfig, attr, &value); | |
if (result != EGL_TRUE) { | |
printf("\nERROR, attr result %d - %s: %d\n", result, attr_name, value); | |
} else { | |
printf("\nattr result %d - %s: %d\n", result, attr_name, value); | |
} | |
fflush(stdout); | |
} | |
void GLInit (void) | |
{ | |
static const EGLint s_configAttribs[] = | |
{ | |
EGL_RED_SIZE, 5, | |
EGL_GREEN_SIZE, 6, | |
EGL_BLUE_SIZE, 5, | |
EGL_ALPHA_SIZE, 0, | |
EGL_SAMPLES, 0, | |
EGL_NONE | |
}; | |
EGLint numconfigs; | |
printf("1"); | |
eglNativeDisplayType = fsl_getNativeDisplay(); | |
printf("2"); | |
egldisplay = eglGetDisplay(eglNativeDisplayType); | |
printf("3"); | |
eglInitialize(egldisplay, NULL, NULL); | |
printf("4"); | |
assert(eglGetError() == EGL_SUCCESS); | |
printf("5"); | |
eglBindAPI(EGL_OPENGL_ES_API); | |
printf("6"); | |
eglChooseConfig(egldisplay, s_configAttribs, &eglconfig, 1, &numconfigs); | |
assert(eglGetError() == EGL_SUCCESS); | |
assert(numconfigs == 1); | |
printf("7"); | |
eglNativeWindow = fsl_createwindow(egldisplay, eglNativeDisplayType); | |
assert(eglNativeWindow); | |
printf("8"); | |
eglsurface = eglCreateWindowSurface(egldisplay, eglconfig, eglNativeWindow, NULL); | |
assert(eglGetError() == EGL_SUCCESS); | |
printf("9"); | |
EGLint ContextAttribList[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; | |
eglcontext = eglCreateContext( egldisplay, eglconfig, EGL_NO_CONTEXT, ContextAttribList ); | |
assert(eglGetError() == EGL_SUCCESS); | |
printf("10"); | |
eglMakeCurrent(egldisplay, eglsurface, eglsurface, eglcontext); | |
assert(eglGetError() == EGL_SUCCESS); | |
// query(EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE"); | |
// query(EGL_RENDER_BUFFER, "EGL_RENDER_BUFFER"); | |
// query(EGL_VG_COLORSPACE, "EGL_VG_COLORSPACE"); //EGL_COLORSPACE_sRGB | |
// query(EGL_VG_ALPHA_FORMAT, "EGL_VG_ALPHA_FORMAT"); //EGL_COLORSPACE_LINEAR | |
// query(EGL_HEIGHT, "EGL_HEIGHT"); | |
// query(EGL_WIDTH, "EGL_WIDTH"); | |
// | |
// queryAttr(EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE"); | |
// queryAttr(EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE"); | |
// queryAttr(EGL_ALPHA_MASK_SIZE, "EGL_ALPHA_MASK_SIZE"); | |
// queryAttr(EGL_BLUE_SIZE, "EGL_BLUE_SIZE"); | |
// queryAttr(EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE"); | |
// queryAttr(EGL_GREEN_SIZE, "EGL_GREEN_SIZE"); | |
// queryAttr(EGL_RED_SIZE, "EGL_RED_SIZE"); | |
// queryAttr(EGL_LEVEL, "EGL_LEVEL"); | |
// queryAttr(EGL_STENCIL_SIZE , "EGL_STENCIL_SIZE"); | |
// queryAttr(EGL_SURFACE_TYPE , "EGL_SURFACE_TYPE"); | |
// queryAttr(EGL_TRANSPARENT_TYPE , "EGL_TRANSPARENT_TYPE"); | |
// queryAttr(EGL_TRANSPARENT_RED_VALUE , "EGL_TRANSPARENT_RED_VALUE"); | |
// queryAttr(EGL_TRANSPARENT_GREEN_VALUE , "EGL_TRANSPARENT_GREEN_VALUE"); | |
// queryAttr(EGL_TRANSPARENT_BLUE_VALUE , "EGL_TRANSPARENT_BLUE_VALUE"); | |
queryAttr(EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE"); | |
queryAttr(EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE"); | |
queryAttr(EGL_BLUE_SIZE, "EGL_BLUE_SIZE"); | |
queryAttr(EGL_GREEN_SIZE, "EGL_GREEN_SIZE"); | |
queryAttr(EGL_RED_SIZE, "EGL_RED_SIZE"); | |
queryAttr(EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE"); | |
queryAttr(EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE"); | |
queryAttr(EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT"); | |
queryAttr(EGL_CONFIG_ID, "EGL_CONFIG_ID"); | |
queryAttr(EGL_LEVEL, "EGL_LEVEL"); | |
queryAttr(EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT"); | |
queryAttr(EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS"); | |
queryAttr(EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH"); | |
queryAttr(EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE"); | |
queryAttr(EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID"); | |
queryAttr(EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE"); | |
queryAttr(EGL_SAMPLES, "EGL_SAMPLES"); | |
queryAttr(EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS"); | |
queryAttr(EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE"); | |
queryAttr(EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE");cd | |
queryAttr(EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE"); | |
queryAttr(EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE"); | |
queryAttr(EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE"); | |
queryAttr(EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB"); | |
queryAttr(EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL"); | |
queryAttr(EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL"); | |
} | |
void GLEnd (void) | |
{ | |
printf("Cleaning up...\n"); | |
eglMakeCurrent(egldisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | |
assert(eglGetError() == EGL_SUCCESS); | |
eglDestroyContext(egldisplay, eglcontext); | |
eglDestroySurface(egldisplay, eglsurface); | |
fsl_destroywindow(eglNativeWindow, eglNativeDisplayType); | |
eglTerminate(egldisplay); | |
assert(eglGetError() == EGL_SUCCESS); | |
eglReleaseThread(); | |
} | |
int main (int argc, char **argv) | |
{ | |
GLInit(); | |
for( int i = 0; i < 100000; ++i) | |
{ | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer | |
switch (i%3) { | |
case 0: | |
glClearColor (1.0f, .0f, .0f, 1.0f); | |
break; | |
case 1: | |
glClearColor (.0f, 1.0f, .0f, 1.0f); | |
break; | |
case 2: | |
glClearColor (.0f, .0f, 1.0f, 1.0f); | |
break; | |
} | |
eglSwapBuffers (egldisplay, eglsurface); | |
sleep(2); | |
} | |
GLEnd(); | |
} | |
//#include <stdio.h> | |
//#include <unistd.h> | |
//#include <stdlib.h> | |
// | |
//#include <EGL/egl.h> | |
//#include <GLES2/gl2.h> | |
// | |
// | |
//static const EGLint configAttribs[] = { | |
// EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | |
// EGL_BLUE_SIZE, 8, | |
// EGL_GREEN_SIZE, 8, | |
// EGL_RED_SIZE, 8, | |
// EGL_DEPTH_SIZE, 0, | |
// | |
// // Uncomment the following to enable MSAA | |
// //EGL_SAMPLE_BUFFERS, 1, // <-- Must be set to 1 to enable multisampling! | |
// //EGL_SAMPLES, 4, // <-- Number of samples | |
// | |
// // Uncomment the following to enable stencil buffer | |
// //EGL_STENCIL_SIZE, 1, | |
// | |
// EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | |
// EGL_NONE | |
//}; | |
// | |
//// Width and height of the desired framebuffer | |
//static const EGLint pbufferAttribs[] = { | |
// EGL_WIDTH, 1024, | |
// EGL_HEIGHT, 768, | |
// EGL_NONE, | |
//}; | |
// | |
//static const EGLint contextAttribs[] = { | |
// EGL_CONTEXT_CLIENT_VERSION, 2, | |
// EGL_NONE | |
//}; | |
// | |
//// The following array holds vec3 data of | |
//// three vertex positions | |
//static const GLfloat vertices[] = { | |
// -1.0f, -1.0f, 0.0f, | |
// 1.0f, -1.0f, 0.0f, | |
// 0.0f, 1.0f, 0.0f, | |
//}; | |
// | |
//// The following are GLSL shaders for rendering a triangle on the screen | |
//#define STRINGIFY(x) #x | |
//static const char* vertexShaderCode = STRINGIFY( | |
// attribute vec3 pos; | |
// void main() { | |
// gl_Position = vec4(pos, 1.0); | |
// } | |
//); | |
// | |
//static const char* fragmentShaderCode = STRINGIFY( | |
// uniform vec4 color; | |
// void main() { | |
// gl_FragColor = vec4(color); | |
// } | |
//); | |
// | |
//static const char* eglGetErrorStr(){ | |
// switch(eglGetError()){ | |
// case EGL_SUCCESS: return "The last function succeeded without error."; | |
// case EGL_NOT_INITIALIZED: return "EGL is not initialized, or could not be initialized, for the specified EGL display connection."; | |
// case EGL_BAD_ACCESS: return "EGL cannot access a requested resource (for example a context is bound in another thread)."; | |
// case EGL_BAD_ALLOC: return "EGL failed to allocate resources for the requested operation."; | |
// case EGL_BAD_ATTRIBUTE: return "An unrecognized attribute or attribute value was passed in the attribute list."; | |
// case EGL_BAD_CONTEXT: return "An EGLContext argument does not name a valid EGL rendering context."; | |
// case EGL_BAD_CONFIG: return "An EGLConfig argument does not name a valid EGL frame buffer configuration."; | |
// case EGL_BAD_CURRENT_SURFACE: return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid."; | |
// case EGL_BAD_DISPLAY: return "An EGLDisplay argument does not name a valid EGL display connection."; | |
// case EGL_BAD_SURFACE: return "An EGLSurface argument does not name a valid surface (window, pixel buffer or pixmap) configured for GL rendering."; | |
// case EGL_BAD_MATCH: return "Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid surface)."; | |
// case EGL_BAD_PARAMETER: return "One or more argument values are invalid."; | |
// case EGL_BAD_NATIVE_PIXMAP: return "A NativePixmapType argument does not refer to a valid native pixmap."; | |
// case EGL_BAD_NATIVE_WINDOW: return "A NativeWindowType argument does not refer to a valid native window."; | |
// case EGL_CONTEXT_LOST: return "A power management event has occurred. The application must destroy all contexts and reinitialise OpenGL ES state and objects to continue rendering."; | |
// default: break; | |
// } | |
// return "Unknown error!"; | |
//} | |
// | |
//int main(int argv, char** argc){ | |
// EGLDisplay display; | |
// int major, minor; | |
// int desiredWidth, desiredHeight; | |
// GLuint program, vert, frag, vbo; | |
// GLint posLoc, colorLoc, result; | |
// | |
// if((display = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY){ | |
// fprintf(stderr, "Failed to get EGL display! Error: %s\n", eglGetErrorStr); | |
// return EXIT_FAILURE; | |
// } | |
// | |
// if(eglInitialize(display, &major, &minor) == EGL_FALSE){ | |
// fprintf(stderr, "Failed to get EGL version! Error: %s\n", eglGetErrorStr); | |
// eglTerminate(display); | |
// return EXIT_FAILURE; | |
// } | |
// | |
// printf("Initialized EGL version: %d.%d\n", major, minor); | |
// | |
// EGLint numConfigs; | |
// EGLConfig config; | |
// if(!eglChooseConfig(display, configAttribs, &config, 1, &numConfigs)){ | |
// fprintf(stderr, "Failed to get EGL config! Error: %s\n", eglGetErrorStr); | |
// eglTerminate(display); | |
// return EXIT_FAILURE; | |
// } | |
// | |
// EGLSurface surface = eglCreatePbufferSurface(display, config, pbufferAttribs); | |
// if(surface == EGL_NO_SURFACE){ | |
// fprintf(stderr, "Failed to create EGL surface! Error: %s\n", eglGetErrorStr); | |
// eglTerminate(display); | |
// return EXIT_FAILURE; | |
// } | |
// | |
// eglBindAPI(EGL_OPENGL_API); | |
// | |
// EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs); | |
// if(context == EGL_NO_CONTEXT){ | |
// fprintf(stderr, "Failed to create EGL context! Error: %s\n", eglGetErrorStr); | |
// eglDestroySurface(display, surface); | |
// eglTerminate(display); | |
// return EXIT_FAILURE; | |
// } | |
// | |
// eglMakeCurrent(display, surface, surface, context); | |
// | |
// // The desired width and height is defined inside of pbufferAttribs | |
// // Check top of this file for EGL_WIDTH and EGL_HEIGHT | |
// desiredWidth = pbufferAttribs[1]; // 800 | |
// desiredHeight = pbufferAttribs[3]; // 600 | |
// | |
// // Set GL Viewport size, always needed! | |
// glViewport(0, 0, desiredWidth, desiredHeight); | |
// | |
// // Get GL Viewport size and test if it is correct. | |
// // NOTE! DO NOT UPDATE EGL LIBRARY ON RASPBERRY PI AS IT WILL INSTALL FAKE EGL! | |
// // If you have fake/faulty EGL library, the glViewport and glGetIntegerv won't work! | |
// // The following piece of code checks if the gl functions are working as intended! | |
// GLint viewport[4]; | |
// glGetIntegerv(GL_VIEWPORT, viewport); | |
// | |
// // viewport[2] and viewport[3] are viewport width and height respectively | |
// printf("GL Viewport size: %dx%d\n", viewport[2], viewport[3]); | |
// | |
// // Test if the desired width and height match the one returned by glGetIntegerv | |
// if(desiredWidth != viewport[2] || desiredHeight != viewport[3]){ | |
// fprintf(stderr, "Error! The glViewport/glGetIntegerv are not working! EGL might be faulty!\n"); | |
// } | |
// | |
// // Clear whole screen (front buffer) | |
// glClearColor(1.0f, 1.0f, 1.0f, 1.0f); | |
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
// | |
// // Create a shader program | |
// // NO ERRRO CHECKING IS DONE! (for the purpose of this example) | |
// // Read an OpenGL tutorial to properly implement shader creation | |
// program = glCreateProgram(); | |
// glUseProgram(program); | |
// vert = glCreateShader(GL_VERTEX_SHADER); | |
// glShaderSource(vert, 1, &vertexShaderCode, NULL); | |
// glCompileShader(vert); | |
// frag = glCreateShader(GL_FRAGMENT_SHADER); | |
// glShaderSource(frag, 1, &fragmentShaderCode, NULL); | |
// glCompileShader(frag); | |
// glAttachShader(program, frag); | |
// glAttachShader(program, vert); | |
// glLinkProgram(program); | |
// glUseProgram(program); | |
// | |
// // Create Vertex Buffer Object | |
// // Again, NO ERRRO CHECKING IS DONE! (for the purpose of this example) | |
// glGenBuffers(1, &vbo); | |
// glBindBuffer(GL_ARRAY_BUFFER, vbo); | |
// glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), vertices, GL_STATIC_DRAW); | |
// | |
// // Get vertex attribute and uniform locations | |
// posLoc = glGetAttribLocation(program, "pos"); | |
// colorLoc = glGetUniformLocation(program, "color"); | |
// | |
// // Set the desired color of the triangle to pink | |
// // 100% red, 0% green, 50% blue, 100% alpha | |
// glUniform4f(colorLoc, 1.0, 0.0f, 0.5, 1.0); | |
// | |
// // Set our vertex data | |
// glEnableVertexAttribArray(posLoc); | |
// glBindBuffer(GL_ARRAY_BUFFER, vbo); | |
// glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); | |
// | |
// // Render a triangle consisting of 3 vertices: | |
// glDrawArrays(GL_TRIANGLES, 0, 3); | |
// | |
// glFinish(); | |
//// eglSwapBuffers(display, surface); | |
//// glFinish(); | |
// | |
//// // Create buffer to hold entire front buffer pixels | |
//// // We multiply width and height by 3 to because we use RGB! | |
//// unsigned char* buffer = (unsigned char*)malloc(desiredWidth * desiredHeight * 3); | |
//// | |
//// // Copy entire screen | |
//// glReadPixels(0, 0, desiredWidth, desiredHeight, GL_RGB, GL_UNSIGNED_BYTE, buffer); | |
//// | |
//// // Write all pixels to file | |
//// FILE* output = fopen("triangle.raw", "wb"); | |
//// if(output){ | |
//// fwrite(buffer, 1, desiredWidth * desiredHeight * 3, output); | |
//// fclose(output); | |
//// } else { | |
//// fprintf(stderr, "Failed to open file triangle.raw for writing!\n"); | |
//// } | |
//// | |
//// // Free copied pixels | |
//// free(buffer); | |
// | |
// // Cleanup | |
// eglDestroyContext(display, context); | |
// eglDestroySurface(display, surface); | |
// eglTerminate(display); | |
// return EXIT_SUCCESS; | |
//} | |
/// FB example | |
//#include <stdint.h> | |
//#include <stdlib.h> | |
// | |
//typedef uint_fast16_t uint; | |
// | |
//typedef struct { | |
// char *buffer; | |
// size_t size, | |
// bytes_per_pixel, bytes_per_line, | |
// width, height; | |
// uint red, green, blue; | |
//} Screen; | |
// | |
//#include <stdio.h> | |
// | |
//#include <fcntl.h> | |
//#include <linux/fb.h> | |
//#include <linux/kd.h> | |
//#include <sys/mman.h> | |
//#include <sys/ioctl.h> | |
//#include <unistd.h> | |
//#include <time.h> | |
// | |
//#define fbdev "/dev/fb0" | |
//#define ttydev "/dev/tty1" | |
// | |
//typedef struct { | |
// uint_fast8_t r, g, b, a; | |
//} Color; | |
// | |
//#define Die(Msg, ...) { \ | |
// fprintf (stderr, "fbgrad: " Msg ".\n", __VA_ARGS__); \ | |
// exit(1); \ | |
//}\ | |
// | |
//#define Assumption(Cond, Msg) \ | |
// if (!(Cond)) { \ | |
// fprintf (stderr, "fbgrad: failed assumption: %s\n", Msg);\ | |
// exit(2);\ | |
// } | |
// | |
//int main (int argc, char **argv) { | |
// int ttyfd = open (ttydev, O_RDWR); | |
// if (ttyfd < 0) | |
// Die ("cannot open \"%s\"", ttydev); | |
// | |
// if (ioctl (ttyfd, KDSETMODE, KD_GRAPHICS) == -1) | |
// Die ("cannot set tty into graphics mode on \"%s\"", ttydev); | |
// | |
// int fbfd = open (fbdev, O_RDWR); | |
// if (fbfd < 0) | |
// Die ("cannot open \"%s\"", fbdev); | |
// | |
// struct fb_var_screeninfo vinf; | |
// struct fb_fix_screeninfo finf; | |
// | |
// if (ioctl (fbfd, FBIOGET_FSCREENINFO, &finf) == -1) | |
// Die ("cannot open fixed screen info for \"%s\"", fbdev); | |
// | |
// if (ioctl (fbfd, FBIOGET_VSCREENINFO, &vinf) == -1) | |
// Die ("cannot open variable screen info for \"%s\"", fbdev); | |
// | |
// | |
// | |
// Assumption ((vinf.red.offset%8) == 0 && (vinf.red.length == 8) && | |
// (vinf.green.offset%8) == 0 && (vinf.green.length == 8) && | |
// (vinf.blue.offset%8) == 0 && (vinf.blue.length == 8) && | |
// (vinf.transp.offset) == 0 && (vinf.transp.length == 0) && | |
// vinf.xoffset == 0 && vinf.yoffset == 0 && | |
// vinf.red.msb_right == 0 && | |
// vinf.green.msb_right == 0 && | |
// vinf.blue.msb_right == 0, | |
// "Color masks are 8bit, byte aligned, little endian, no transparency." | |
// ); | |
// | |
// Screen s = { | |
// .size = finf.line_length * vinf.yres, | |
// .bytes_per_pixel = vinf.bits_per_pixel / 8, | |
// .bytes_per_line = finf.line_length, | |
// .red = vinf.red.offset/8, | |
// .green = vinf.green.offset/8, | |
// .blue = vinf.blue.offset/8, | |
// .width = vinf.xres, | |
// .height = vinf.yres | |
// }; | |
// | |
// s.buffer = mmap (0, s.size, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); | |
// | |
// if (s.buffer == MAP_FAILED) | |
// Die ("cannot map frame buffer \"%s\"", fbdev); | |
// | |
// int time_start = time (NULL); | |
// | |
// for (uint t = 0; t < 255; t++) { | |
// for (uint y = 0; y < vinf.yres; y++) { | |
// for (uint x = 0; x < vinf.xres; x++) { | |
// uint pix_offset = x * s.bytes_per_pixel + y * s.bytes_per_line; | |
// s.buffer[pix_offset + s.red] = x * 255 / s.width; | |
// s.buffer[pix_offset + s.green] = y * 255 / s.height; | |
// s.buffer[pix_offset + s.blue] = t; | |
// } | |
// } | |
// } | |
// | |
// int time_end = time(NULL); | |
// | |
// munmap (s.buffer, s.size); | |
// | |
// if (ioctl (ttyfd, KDSETMODE, KD_TEXT) == -1) | |
// Die ("cannot set tty into text mode on \"%s\"", ttydev); | |
// | |
// close (fbfd); | |
// close (ttyfd); | |
// | |
// printf ("FPS: %.2f.\n", 255.0 / (time_end - time_start)); | |
// | |
// return EXIT_SUCCESS; | |
//} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment