Bool glXMakeCurrent(Display *display, int drawable, GLXContext context) { if (eglDisplay != NULL) { eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); if (eglSurface != NULL) { eglDestroySurface(eglDisplay, eglSurface); } } // call with NULL to just destroy old stuff. if (! context) { return true; } if (eglDisplay == NULL) { init_display(display); } if (g_usefb) drawable = 0; eglSurface = eglCreateWindowSurface(eglDisplay, eglConfigs[0], drawable, NULL); CheckEGLErrors(); EGLBoolean result = eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); CheckEGLErrors(); if (result) { return true; } return false; }
/*======================================================== * Init base EGL * ======================================================*/ int8_t EGL_Open( void ) { EGLBoolean result; const char* output; // Setup any platform specific bits Platform_Open(); #if defined(USE_EGL_SDL) printf( "EGL Opening X11 display\n" ); g_Display = XOpenDisplay(NULL); if (g_Display == NULL) { printf( "EGL ERROR: unable to get display!\n" ); return 1; } #endif /* defined(USE_EGL_SDL) */ printf( "EGL Getting EGL display\n" ); g_eglDisplay = peglGetDisplay( (NativeDisplayType)g_Display ); if (g_eglDisplay == EGL_NO_DISPLAY) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGL ERROR: Unable to create EGL display.\n" ); return 1; } printf( "EGL Initializing\n" ); result = peglInitialize( g_eglDisplay, NULL, NULL ); if (result != EGL_TRUE ) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGL ERROR: Unable to initialize EGL display.\n" ); return 1; } // Get EGL Library Information output = peglQueryString( g_eglDisplay, EGL_VENDOR ); printf( "EGL_VENDOR: %s\n", output ); output = peglQueryString( g_eglDisplay, EGL_VERSION ); printf( "EGL_VERSION: %s\n", output ); output = peglQueryString( g_eglDisplay, EGL_EXTENSIONS ); printf( "EGL_EXTENSIONS: %s\n", output ); CheckEGLErrors( __FILE__, __LINE__ ); return 0; }
/** @brief Release all EGL and system resources */ void EGL_Close( void ) { /* Release EGL resources */ if (eglDisplay != NULL) { peglMakeCurrent( eglDisplay, NULL, NULL, EGL_NO_CONTEXT ); if (eglContext != NULL) { peglDestroyContext( eglDisplay, eglContext ); } if (eglSurface != NULL) { peglDestroySurface( eglDisplay, eglSurface ); } peglTerminate( eglDisplay ); } eglSurface = NULL; eglContext = NULL; eglDisplay = NULL; eglColorbits = 0; eglDepthbits = 0; eglStencilbits = 0; /* Release platform resources */ FreeNativeWindow(); FreeNativeDisplay(); Platform_Close(); CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGLport: Closed\n" ); }
static EGLConfig GetBestEGLConfig(EGLDisplay display, const EGLint* attribList) { EGLint numConfigs; if (eglGetConfigs(display, NULL, 0, &numConfigs) == EGL_FALSE) { CheckEGLErrors(); } std::vector<EGLConfig> configs(numConfigs); EGLint numChosenConfigs; if (eglChooseConfig(display, attribList, configs.data(), configs.size(), &numChosenConfigs) == EGL_FALSE) { CheckEGLErrors(); } // pick the config with the most samples per pixel int bestConfigIndex = -1, bestNumSamples = -1; for (int i = 0; i < numChosenConfigs; i++) { EGLint sampleBuffers; EGLint numSamples; EGLBoolean sampleBufferStatus = eglGetConfigAttrib(display, configs[i], EGL_SAMPLE_BUFFERS, &sampleBuffers); EGLBoolean numSamplesStatus = eglGetConfigAttrib(display, configs[i], EGL_SAMPLES, &numSamples); if (sampleBufferStatus == EGL_FALSE || numSamplesStatus == EGL_FALSE) { CheckEGLErrors(); } if (bestConfigIndex < 0 || (sampleBuffers && numSamples > bestNumSamples)) { bestConfigIndex = i; bestNumSamples = numSamples; } } if (bestConfigIndex == -1) { throw std::runtime_error("No best EGLConfig"); } return configs[bestConfigIndex]; }
ngEGLContext(EGLDisplay display, EGLConfig config, EGLContext shareContext, const EGLint* attribList) : mDisplay(display) { mContext = eglCreateContext(mDisplay, config, shareContext, attribList); if (mContext == EGL_NO_CONTEXT) { CheckEGLErrors(); } }
/** @brief Find a EGL configuration tht matches the defined attributes * @return : 0 if the function passed, else 1 */ int8_t FindEGLConfigs( void ) { EGLBoolean result; int attrib = 0; EGLint ConfigAttribs[23]; ConfigAttribs[attrib++] = EGL_RED_SIZE; /* 1 */ ConfigAttribs[attrib++] = eglSettings[CFG_RED_SIZE]; /* 2 */ ConfigAttribs[attrib++] = EGL_GREEN_SIZE; /* 3 */ ConfigAttribs[attrib++] = eglSettings[CFG_GREEN_SIZE]; /* 4 */ ConfigAttribs[attrib++] = EGL_BLUE_SIZE; /* 5 */ ConfigAttribs[attrib++] = eglSettings[CFG_BLUE_SIZE]; /* 6 */ ConfigAttribs[attrib++] = EGL_ALPHA_SIZE; /* 7 */ ConfigAttribs[attrib++] = eglSettings[CFG_ALPHA_SIZE]; /* 8 */ ConfigAttribs[attrib++] = EGL_DEPTH_SIZE; /* 9 */ ConfigAttribs[attrib++] = eglSettings[CFG_DEPTH_SIZE]; /* 10 */ ConfigAttribs[attrib++] = EGL_BUFFER_SIZE; /* 11 */ ConfigAttribs[attrib++] = eglSettings[CFG_BUFFER_SIZE]; /* 12 */ ConfigAttribs[attrib++] = EGL_STENCIL_SIZE; /* 13 */ ConfigAttribs[attrib++] = eglSettings[CFG_STENCIL_SIZE]; /* 14 */ ConfigAttribs[attrib++] = EGL_SURFACE_TYPE; /* 15 */ ConfigAttribs[attrib++] = EGL_WINDOW_BIT; /* 16 */ #if defined(EGL_VERSION_1_2) ConfigAttribs[attrib++] = EGL_RENDERABLE_TYPE; /* 17 */ #if defined(USE_GLES1) ConfigAttribs[attrib++] = EGL_OPENGL_ES_BIT; #else ConfigAttribs[attrib++] = EGL_OPENGL_ES2_BIT; /* 18 */ #endif /* USE_GLES1 */ #endif /* EGL_VERSION_1_2 */ ConfigAttribs[attrib++] = EGL_SAMPLE_BUFFERS; /* 19 */ ConfigAttribs[attrib++] = (eglSettings[CFG_FSAA] > 0) ? 1 : 0; /* 20 */ ConfigAttribs[attrib++] = EGL_SAMPLES; /* 21 */ ConfigAttribs[attrib++] = eglSettings[CFG_FSAA]; /* 22 */ ConfigAttribs[attrib++] = EGL_NONE; /* 23 */ result = peglChooseConfig( eglDisplay, ConfigAttribs, eglConfigs, totalConfigsIn, &totalConfigsFound ); if (result != EGL_TRUE || totalConfigsFound == 0) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGLport ERROR: Unable to query for available configs, found %d.\n", totalConfigsFound ); printf("Attrib were:\n"); int ii=0; while (ConfigAttribs[ii]!=EGL_NONE) { printf("\t%04X, %04X\n", ConfigAttribs[ii], ConfigAttribs[ii+1]); ii+=2; } return 1; } printf( "EGLport: Found %d available configs\n", totalConfigsFound ); return 0; }
ngEGLDisplay(NativeWindowType nativeDisplay) { mDisplay = eglGetDisplay(nativeDisplay); if (mDisplay == EGL_NO_DISPLAY) { throw std::runtime_error("No display connection matching nativeDisplay is available"); } if (eglInitialize(mDisplay, NULL, NULL) == EGL_FALSE) { CheckEGLErrors(); } }
ngEWindow(const VideoFlags& videoFlags, EGLDisplay dpy, EGLConfig config, EGLNativeWindowType nativeWindow, const EGLint* attribList) : mVideoFlags(videoFlags) , mDisplay(dpy) { mSurface = eglCreateWindowSurface(mDisplay, config, nativeWindow, attribList); if (mSurface == EGL_NO_SURFACE) { CheckEGLErrors(); } }
void glXSwapBuffers(Display *display, int drawable) { static int frames = 0; render_raster(); if (g_vsync && fbdev >= 0) { // TODO: can I just return if I don't meet vsync over multiple frames? // this will just block otherwise. int arg = 0; for (int i = 0; i < swap_interval; i++) { ioctl(fbdev, FBIO_WAITFORVSYNC, &arg); } } eglSwapBuffers(eglDisplay, eglSurface); CheckEGLErrors(); if (g_showfps) { // framerate counter static float avg, fps = 0; static int frame1, last_frame, frame, now, current_frames; struct timeval out; gettimeofday(&out, NULL); now = out.tv_sec; frame++; current_frames++; if (frame == 1) { frame1 = now; } else if (frame1 < now) { if (last_frame < now) { float change = current_frames / (float)(now - last_frame); float weight = 0.7; if (! fps) { fps = change; } else { fps = (1 - weight) * fps + weight * change; } current_frames = 0; avg = frame / (float)(now - frame1); printf("libGL fps: %.2f, avg: %.2f\n", fps, avg); } } last_frame = now; } }
/*======================================================= * Detect available video resolutions =======================================================*/ int8_t FindAppropriateEGLConfigs( void ) { EGLBoolean result; int attrib = 0; EGLint ConfigAttribs[17]; ConfigAttribs[attrib++] = EGL_RED_SIZE; ConfigAttribs[attrib++] = 5; ConfigAttribs[attrib++] = EGL_GREEN_SIZE; ConfigAttribs[attrib++] = 6; ConfigAttribs[attrib++] = EGL_BLUE_SIZE; ConfigAttribs[attrib++] = 5; ConfigAttribs[attrib++] = EGL_DEPTH_SIZE; ConfigAttribs[attrib++] = 16; ConfigAttribs[attrib++] = EGL_SURFACE_TYPE; ConfigAttribs[attrib++] = EGL_WINDOW_BIT; #if defined(EGL_VERSION_1_2) ConfigAttribs[attrib++] = EGL_RENDERABLE_TYPE; #if defined(USE_GLES1) ConfigAttribs[attrib++] = EGL_OPENGL_ES_BIT; #elif defined(USE_GLES2) ConfigAttribs[attrib++] = EGL_OPENGL_ES2_BIT; #endif /* defined(USE_GLES1) */ #endif /* defined(EGL_VERSION_1_2) */ ConfigAttribs[attrib++] = EGL_SAMPLE_BUFFERS; ConfigAttribs[attrib++] = (FSAA > 0) ? 1 : 0; ConfigAttribs[attrib++] = EGL_SAMPLES; ConfigAttribs[attrib++] = FSAA; ConfigAttribs[attrib++] = EGL_NONE; result = peglChooseConfig( g_eglDisplay, ConfigAttribs, g_allConfigs, g_totalConfigsIn, &g_totalConfigsFound ); if (result != EGL_TRUE || g_totalConfigsFound == 0) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGL ERROR: Unable to query for available configs, found %d.\n", g_totalConfigsFound ); return 1; } printf( "EGL Found %d available configs\n", g_totalConfigsFound ); return 0; }
/*=========================================================== Setup EGL context and surface ===========================================================*/ int8_t EGL_Init( void ) { int configIndex = 0; if (FindAppropriateEGLConfigs() != 0) { printf( "EGL ERROR: Unable to configure EGL. See previous error.\n" ); return 1; } printf( "EGL Config %d\n", configIndex ); if ( ConfigureEGL(g_allConfigs[configIndex]) != 0) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGL ERROR: Unable to configure EGL. See previous error.\n" ); return 1; } return 0; }
/*====================================================== * Close EGL resources ====================================================*/ void EGL_Close() { if (g_eglDisplay != NULL) { peglMakeCurrent( g_eglDisplay, NULL, NULL, EGL_NO_CONTEXT ); if (g_eglContext != NULL) { peglDestroyContext( g_eglDisplay, g_eglContext ); } if (g_eglSurface != NULL) { peglDestroySurface( g_eglDisplay, g_eglSurface ); } peglTerminate( g_eglDisplay ); } g_eglSurface = NULL; g_eglContext = NULL; g_eglDisplay = NULL; #if defined(USE_EGL_RAW) if (g_Window != NULL) { free(g_Window); } g_Window = NULL; #elif defined(USE_EGL_SDL) if (g_Display != NULL) { XCloseDisplay(g_Display); } g_Display = NULL; #else #error Incorrect EGL Configuration #endif /* defined(USE_EGL_RAW) */ CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGL Closed\n" ); Platform_Close(); }
/** @brief Obtain the system display and initialize EGL * @param width : desired pixel width of the window (not used by all platforms) * @param height : desired pixel height of the window (not used by all platforms) * @return : 0 if the function passed, else 1 */ int8_t EGL_Open( uint16_t width, uint16_t height ) { EGLint eglMajorVer, eglMinorVer; EGLBoolean result; uint32_t configIndex = 0; const char* output; static const EGLint contextAttribs[] = { #if defined(USE_GLES2) EGL_CONTEXT_CLIENT_VERSION, 2, #endif EGL_NONE }; #if defined(DEBUG) printf( "EGLport Warning: DEBUG is enabled which may effect performance\n" ); #endif /* Check that system is not open */ if (eglDisplay != NULL || eglContext != NULL || eglSurface != NULL) { printf( "EGLport ERROR: EGL system is already open!\n" ); return 1; } /* Check for the cfg file to alternative settings */ OpenCfg( "eglport.cfg" ); /* Setup any platform specific bits */ Platform_Open(); printf( "EGLport: Opening EGL display\n" ); if (GetNativeDisplay() != 0) { printf( "EGLport ERROR: Unable to obtain native display!\n" ); return 1; } eglDisplay = peglGetDisplay( nativeDisplay ); if (eglDisplay == EGL_NO_DISPLAY) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGLport ERROR: Unable to create EGL display.\n" ); return 1; } printf( "EGLport: Initializing\n" ); result = peglInitialize( eglDisplay, &eglMajorVer, &eglMinorVer ); if (result != EGL_TRUE ) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGLport ERROR: Unable to initialize EGL display.\n" ); return 1; } /* Get EGL Library Information */ printf( "EGL Implementation Version: Major %d Minor %d\n", eglMajorVer, eglMinorVer ); output = peglQueryString( eglDisplay, EGL_VENDOR ); printf( "EGL_VENDOR: %s\n", output ); output = peglQueryString( eglDisplay, EGL_VERSION ); printf( "EGL_VERSION: %s\n", output ); output = peglQueryString( eglDisplay, EGL_EXTENSIONS ); printf( "EGL_EXTENSIONS: %s\n", output ); if (FindEGLConfigs() != 0) { printf( "EGLport ERROR: Unable to configure EGL. See previous error.\n" ); return 1; } printf( "EGLport: Using Config %d\n", configIndex ); #if defined(EGL_VERSION_1_2) /* Bind GLES and create the context */ printf( "EGLport: Binding API\n" ); result = peglBindAPI( EGL_OPENGL_ES_API ); if ( result == EGL_FALSE ) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGLport ERROR: Could not bind EGL API.\n" ); return 1; } #endif /* EGL_VERSION_1_2 */ printf( "EGLport: Creating Context\n" ); eglContext = peglCreateContext( eglDisplay, eglConfigs[configIndex], NULL, contextAttribs ); if (eglContext == EGL_NO_CONTEXT) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGLport ERROR: Unable to create GLES context!\n"); return 1; } printf( "EGLport: Creating window surface\n" ); if (GetNativeWindow( width, height ) != 0) { printf( "EGLport ERROR: Unable to obtain native window!\n" ); return 1; } eglSurface = peglCreateWindowSurface( eglDisplay, eglConfigs[configIndex], nativeWindow, 0 ); if (eglSurface == EGL_NO_SURFACE) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGLport ERROR: Unable to create EGL surface!\n" ); return 1; } printf( "EGLport: Making Current\n" ); result = peglMakeCurrent( eglDisplay, eglSurface, eglSurface, eglContext ); if (result != EGL_TRUE) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGLport ERROR: Unable to make GLES context current\n" ); return 1; } { EGLint color, depth, stencil; eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_BUFFER_SIZE, &color); eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_DEPTH_SIZE, &depth); eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_STENCIL_SIZE, &stencil); eglColorbits = (color==16)?5:8; //quick hack eglDepthbits = depth; eglStencilbits = stencil; } printf( "EGLport: Setting swap interval\n" ); peglSwapInterval( eglDisplay, (eglSettings[CFG_VSYNC] > 0) ? 1 : 0 ); printf( "EGLport: Complete\n" ); CheckEGLErrors( __FILE__, __LINE__ ); return 0; }
GLXContext glXCreateContext(Display *display, XVisualInfo *visual, GLXContext shareList, Bool isDirect) { EGLint configAttribs[] = { #ifdef PANDORA EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, #endif EGL_DEPTH_SIZE, 16, #ifdef USE_ES2 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #else EGL_BUFFER_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, #endif EGL_NONE }; #ifdef USE_ES2 EGLint attrib_list[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; #else EGLint *attrib_list = NULL; #endif scan_env(); #ifdef BCMHOST if (! g_bcm_active) { g_bcm_active = true; bcm_host_init(); } #endif GLXContext fake = malloc(sizeof(struct __GLXContextRec)); if (eglDisplay != NULL) { eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); if (eglContext != NULL) { eglDestroyContext(eglDisplay, eglContext); eglContext = NULL; } if (eglSurface != NULL) { eglDestroySurface(eglDisplay, eglSurface); eglSurface = NULL; } } // make an egl context here... EGLBoolean result; if (eglDisplay == NULL || eglDisplay == EGL_NO_DISPLAY) { if (xDisplay == NULL) { xDisplay = display; } if (g_usefb) { eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); } else { eglDisplay = eglGetDisplay(xDisplay); } if (eglDisplay == EGL_NO_DISPLAY) { printf("Unable to create EGL display.\n"); return fake; } } // first time? if (eglInitialized == false) { eglBindAPI(EGL_OPENGL_ES_API); result = eglInitialize(eglDisplay, NULL, NULL); if (result != EGL_TRUE) { printf("Unable to initialize EGL display.\n"); return fake; } eglInitialized = true; } int configsFound; result = eglChooseConfig(eglDisplay, configAttribs, eglConfigs, 1, &configsFound); CheckEGLErrors(); if (result != EGL_TRUE || configsFound == 0) { printf("No EGL configs found.\n"); return fake; } eglContext = eglCreateContext(eglDisplay, eglConfigs[0], EGL_NO_CONTEXT, attrib_list); CheckEGLErrors(); // need to return a glx context pointing at it fake->display = xDisplay; fake->direct = true; fake->xid = 1; return fake; }
/*=========================================================== Initialise OpenGL settings ===========================================================*/ int8_t ConfigureEGL(EGLConfig config) { EGLBoolean result; #if defined(USE_GLES1) static const EGLint s_contextAttribs = NULL; #elif defined(USE_GLES2) static const EGLint s_contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; #else #error Incorrect Opengl-ES Configuration for s_contextAttribs #endif /* defined(USE_GLES1) */ // Cleanup in case of a reset if (g_eglDisplay != NULL) { peglMakeCurrent( g_eglDisplay, NULL, NULL, EGL_NO_CONTEXT ); if (g_eglContext != NULL) { peglDestroyContext( g_eglDisplay, g_eglContext ); } if (g_eglSurface != NULL) { peglDestroySurface( g_eglDisplay, g_eglSurface ); } } #if defined(EGL_VERSION_1_2) // Bind GLES and create the context printf( "EGL Binding API\n" ); peglBindAPI( EGL_OPENGL_ES_API ); if ( CheckEGLErrors( __FILE__, __LINE__ ) != 0 ) { printf( "EGL ERROR: Could not bind EGL API.\n" ); return 1; } #endif /* defined(USE_EGL_SDL) */ printf( "EGL Creating Context\n" ); g_eglContext = peglCreateContext( g_eglDisplay, config, NULL, s_contextAttribs ); if (g_eglContext == EGL_NO_CONTEXT) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGL ERROR: Unable to create GLES context!\n"); return 1; } #if defined(USE_EGL_RAW) if (g_Window == NULL) { g_Window = (NativeWindowType)malloc(16*1024); if(g_Window == NULL) { printf( "EGL ERROR: Memory for window Failed\n" ); return 1; } } else { printf( "EGL Info: Memory for window already allocated\n" ); } #elif defined(USE_EGL_SDL) // Get the SDL window handle SDL_SysWMinfo sysInfo; //Will hold our Window information SDL_VERSION(&sysInfo.version); //Set SDL version if(SDL_GetWMInfo(&sysInfo) <= 0) { printf( "EGL ERROR: Unable to get SDL window handle: %s\n", SDL_GetError() ); return 1; } g_Window = (NativeWindowType)sysInfo.info.x11.window; #else #error Incorrect EGL Configuration for g_Window #endif /* defined(USE_EGL_RAW) */ printf( "EGL Creating window surface\n" ); g_eglSurface = peglCreateWindowSurface( g_eglDisplay, config, g_Window, 0 ); if (g_eglSurface == EGL_NO_SURFACE) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGL ERROR: Unable to create EGL surface!\n" ); return 1; } printf( "EGL Making Current\n" ); result = peglMakeCurrent( g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext ); if (result != EGL_TRUE) { CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGL ERROR: Unable to make GLES context current\n" ); return 1; } CheckEGLErrors( __FILE__, __LINE__ ); printf( "EGL Complete\n" ); return 0; }