bool CWinSystemX11::SetWindow(int width, int height, bool fullscreen, const std::string &output) { bool changeWindow = false; bool changeSize = false; float mouseX = 0.5; float mouseY = 0.5; if (!m_mainWindow) { CInputManager::GetInstance().SetMouseActive(false); } if (m_mainWindow && ((m_bFullScreen != fullscreen) || m_currentOutput.compare(output) != 0 || m_windowDirty)) { // set mouse to last known position // we can't trust values after an xrr event if (m_bIsInternalXrr && m_MouseX >= 0 && m_MouseY >= 0) { mouseX = (float)m_MouseX/m_nWidth; mouseY = (float)m_MouseY/m_nHeight; } else if (!m_windowDirty) { Window root_return, child_return; int root_x_return, root_y_return; int win_x_return, win_y_return; unsigned int mask_return; bool isInWin = XQueryPointer(m_dpy, m_mainWindow, &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &mask_return); if (isInWin) { mouseX = (float)win_x_return/m_nWidth; mouseY = (float)win_y_return/m_nHeight; } } CInputManager::GetInstance().SetMouseActive(false); OnLostDevice(); DestroyWindow(); m_windowDirty = true; } // create main window if (!m_mainWindow) { EnableSystemScreenSaver(false); #if defined(HAS_GLX) GLint att[] = { GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_ALPHA_SIZE, 8, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; #endif #if defined(HAS_EGL) EGLint att[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_BUFFER_SIZE, 32, EGL_DEPTH_SIZE, 24, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; #endif Colormap cmap; XSetWindowAttributes swa; XVisualInfo *vi; int x0 = 0; int y0 = 0; XOutput *out = g_xrandr.GetOutput(output); if (!out) out = g_xrandr.GetOutput(m_currentOutput); if (out) { m_nScreen = out->screen; x0 = out->x; y0 = out->y; } #if defined(HAS_GLX) vi = glXChooseVisual(m_dpy, m_nScreen, att); #endif #if defined(HAS_EGL) if (m_eglDisplay == EGL_NO_DISPLAY) { m_eglDisplay = eglGetDisplay((EGLNativeDisplayType)m_dpy); if (m_eglDisplay == EGL_NO_DISPLAY) { CLog::Log(LOGERROR, "failed to get egl display\n"); return false; } if (!eglInitialize(m_eglDisplay, NULL, NULL)) { CLog::Log(LOGERROR, "failed to initialize egl display\n"); return false; } } EGLint numConfigs; EGLConfig eglConfig = 0; if (!eglChooseConfig(m_eglDisplay, att, &eglConfig, 1, &numConfigs) || numConfigs == 0) { CLog::Log(LOGERROR, "Failed to choose a config %d\n", eglGetError()); } m_eglConfig=eglConfig; EGLint eglVisualid; if (!eglGetConfigAttrib(m_eglDisplay, m_eglConfig, EGL_NATIVE_VISUAL_ID, &eglVisualid)) { CLog::Log(LOGERROR, "Failed to query native visual id\n"); } XVisualInfo x11_visual_info_template; x11_visual_info_template.visualid = eglVisualid; int num_visuals; vi = XGetVisualInfo(m_dpy, VisualIDMask, &x11_visual_info_template, &num_visuals); #endif if(!vi) { CLog::Log(LOGERROR, "Failed to find matching visual"); return false; } cmap = XCreateColormap(m_dpy, RootWindow(m_dpy, vi->screen), vi->visual, AllocNone); bool hasWM = HasWindowManager(); int def_vis = (vi->visual == DefaultVisual(m_dpy, vi->screen)); swa.override_redirect = hasWM ? False : True; swa.border_pixel = fullscreen ? 0 : 5; swa.background_pixel = def_vis ? BlackPixel(m_dpy, vi->screen) : 0; swa.colormap = cmap; swa.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | PropertyChangeMask | StructureNotifyMask | KeymapStateMask | EnterWindowMask | LeaveWindowMask | ExposureMask; unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWEventMask; m_mainWindow = XCreateWindow(m_dpy, RootWindow(m_dpy, vi->screen), x0, y0, width, height, 0, vi->depth, InputOutput, vi->visual, mask, &swa); swa.override_redirect = False; swa.border_pixel = 0; swa.event_mask = ExposureMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWOverrideRedirect | CWColormap | CWEventMask; m_glWindow = XCreateWindow(m_dpy, m_mainWindow, 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, mask, &swa); if (fullscreen && hasWM) { Atom fs = XInternAtom(m_dpy, "_NET_WM_STATE_FULLSCREEN", True); XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_NET_WM_STATE", True), XA_ATOM, 32, PropModeReplace, (unsigned char *) &fs, 1); // disable desktop compositing for KDE, when Kodi is in full-screen mode int one = 1; XChangeProperty(m_dpy, m_mainWindow, XInternAtom(m_dpy, "_KDE_NET_WM_BLOCK_COMPOSITING", True), XA_CARDINAL, 32, PropModeReplace, (unsigned char*) &one, 1); } // define invisible cursor Pixmap bitmapNoData; XColor black; static char noData[] = { 0,0,0,0,0,0,0,0 }; black.red = black.green = black.blue = 0; bitmapNoData = XCreateBitmapFromData(m_dpy, m_mainWindow, noData, 8, 8); m_invisibleCursor = XCreatePixmapCursor(m_dpy, bitmapNoData, bitmapNoData, &black, &black, 0, 0); XFreePixmap(m_dpy, bitmapNoData); XDefineCursor(m_dpy,m_mainWindow, m_invisibleCursor); //init X11 events CWinEventsX11Imp::Init(m_dpy, m_mainWindow); changeWindow = true; changeSize = true; #if defined(HAS_EGL) m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, m_glWindow, NULL); if (m_eglSurface == EGL_NO_SURFACE) { CLog::Log(LOGERROR, "failed to create egl window surface\n"); return false; } #endif } if (!CWinEventsX11Imp::HasStructureChanged() && ((width != m_nWidth) || (height != m_nHeight))) { changeSize = true; } if (changeSize || changeWindow) { XResizeWindow(m_dpy, m_mainWindow, width, height); } if ((width != m_nWidth) || (height != m_nHeight) || changeWindow) { XResizeWindow(m_dpy, m_glWindow, width, height); } if (changeWindow) { m_icon = None; { CreateIconPixmap(); XWMHints *wm_hints; XClassHint *class_hints; XTextProperty windowName, iconName; std::string titleString = CCompileInfo::GetAppName(); std::string classString = titleString; char *title = (char*)titleString.c_str(); XStringListToTextProperty(&title, 1, &windowName); XStringListToTextProperty(&title, 1, &iconName); wm_hints = XAllocWMHints(); wm_hints->initial_state = NormalState; wm_hints->icon_pixmap = m_icon; wm_hints->flags = StateHint | IconPixmapHint; class_hints = XAllocClassHint(); class_hints->res_class = (char*)classString.c_str(); class_hints->res_name = (char*)classString.c_str(); XSetWMProperties(m_dpy, m_mainWindow, &windowName, &iconName, NULL, 0, NULL, wm_hints, class_hints); XFree(class_hints); XFree(wm_hints); // register interest in the delete window message Atom wmDeleteMessage = XInternAtom(m_dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(m_dpy, m_mainWindow, &wmDeleteMessage, 1); } // placement of window may follow mouse XWarpPointer(m_dpy, None, m_mainWindow, 0, 0, 0, 0, mouseX*width, mouseY*height); XMapRaised(m_dpy, m_glWindow); XMapRaised(m_dpy, m_mainWindow); // discard events generated by creating the window, i.e. xrr events XSync(m_dpy, TRUE); CDirtyRegionList dr; RefreshGlxContext(m_currentOutput.compare(output) != 0); XSync(m_dpy, FALSE); g_graphicsContext.Clear(0); g_graphicsContext.Flip(dr); #if defined(HAS_GLX) g_Windowing.ResetVSync(); #endif m_windowDirty = false; m_bIsInternalXrr = false; // what's this??? #if defined(HAS_GLX) CSingleLock lock(m_resourceSection); // tell any shared resources for (std::vector<IDispResource *>::iterator i = m_resources.begin(); i != m_resources.end(); ++i) (*i)->OnResetDevice(); #endif } UpdateCrtc(); return true; }
static bool gfx_ctx_init(void) { struct android_app *android_app = (struct android_app*)g_android; const EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE }; EGLint num_config; EGLint egl_version_major, egl_version_minor; EGLint format; EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; RARCH_LOG("Initializing context\n"); if ((g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY) { RARCH_ERR("eglGetDisplay failed.\n"); goto error; } if (!eglInitialize(g_egl_dpy, &egl_version_major, &egl_version_minor)) { RARCH_ERR("eglInitialize failed.\n"); goto error; } RARCH_LOG("[ANDROID/EGL]: EGL version: %d.%d\n", egl_version_major, egl_version_minor); if (!eglChooseConfig(g_egl_dpy, attribs, &g_config, 1, &num_config)) { RARCH_ERR("eglChooseConfig failed.\n"); goto error; } int var = eglGetConfigAttrib(g_egl_dpy, g_config, EGL_NATIVE_VISUAL_ID, &format); if (!var) { RARCH_ERR("eglGetConfigAttrib failed: %d.\n", var); goto error; } ANativeWindow_setBuffersGeometry(android_app->window, 0, 0, format); if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, android_app->window, 0))) { RARCH_ERR("eglCreateWindowSurface failed.\n"); goto error; } if (!(g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, 0, context_attributes))) { RARCH_ERR("eglCreateContext failed.\n"); goto error; } if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx)) { RARCH_ERR("eglMakeCurrent failed.\n"); goto error; } ALooper *looper = ALooper_forThread(); if (!looper) ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); return true; error: RARCH_ERR("EGL error: %d.\n", eglGetError()); gfx_ctx_destroy(); return false; }
/** * Initialize an EGL context for the current display. */ static int engine_init_display(struct engine* engine) { // initialize OpenGL ES and EGL /* * Here specify the attributes of the desired configuration. * Below, we select an EGLConfig with at least 8 bits per color * component compatible with on-screen windows */ const EGLint attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE }; EGLint w, h, format; EGLint numConfigs; EGLConfig config; EGLSurface surface; EGLContext context; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0); /* Here, the application chooses the configuration it desires. In this * sample, we have a very simplified selection process, where we pick * the first EGLConfig that matches our criteria */ eglChooseConfig(display, attribs, &config, 1, &numConfigs); /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). * As soon as we picked a EGLConfig, we can safely reconfigure the * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format); // ANativeActivity_setWindowFlags(engine->app->activity, AWINDOW_FLAG_FULLSCREEN, 0 ); surface = eglCreateWindowSurface(display, config, engine->app->window, NULL); context = eglCreateContext(display, config, NULL, NULL); if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { LOGW("Unable to eglMakeCurrent"); return -1; } eglQuerySurface(display, surface, EGL_WIDTH, &w); eglQuerySurface(display, surface, EGL_HEIGHT, &h); engine->display = display; engine->context = context; engine->surface = surface; engine->width = w; engine->height = h; pangolin::process::Resize(engine->width,engine->height); // Initialize GL state. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); glEnable(GL_CULL_FACE); glShadeModel(GL_SMOOTH); glDisable(GL_DEPTH_TEST); return 0; }
/** * Initialize EGL by specified params * Create a Window Surface for on-screen render */ int initEGL(SdkEnv *env) { LOG_ENTRY; VALIDATE_NOT_NULL(env); VALIDATE_NOT_NULL(env->egl.window); env->egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (EGL_NO_DISPLAY == env->egl.display || EGL_SUCCESS != eglGetError()) { LogE("Failed eglGetDisplay\n"); return -1; } EGLint major, minor; if (!eglInitialize(env->egl.display, &major, &minor) || EGL_SUCCESS != eglGetError()) { LogE("Failed eglInitialize\n"); return -1; } Log("EGL %d.%d\n", major, minor); EGLConfig configs[2]; EGLint numConfigs; if (eglGetConfigs(env->egl.display, configs, 2, &numConfigs) == EGL_FALSE || EGL_SUCCESS != eglGetError()) { LogE("Failed eglGetConfigs\n"); return -1; } EGLint cfg_attrs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE }; if (!eglChooseConfig(env->egl.display, cfg_attrs, configs, 2, &numConfigs) || numConfigs < 1) { LogE("Failed eglChooseConfig\n"); return -1; } EGLint surface_attrs[] = { EGL_NONE }; env->egl.surface = eglCreateWindowSurface(env->egl.display, configs[0], env->egl.window, surface_attrs); if (EGL_NO_SURFACE == env->egl.surface) { LogE("Failed create Window Surface, error code:%x\n", eglGetError()); return -1; } if (!eglBindAPI(EGL_OPENGL_ES_API)) { LogE("Failed eglBindAPI\n"); return -1; } EGLint context_attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; env->egl.context = eglCreateContext(env->egl.display, configs[0], EGL_NO_CONTEXT, context_attrs); if (EGL_NO_CONTEXT == env->egl.context) { LogE("Failed create context, error code:%x\n", eglGetError() ); return -1; } if (!eglMakeCurrent(env->egl.display, env->egl.surface, env->egl.surface, env->egl.context)) { LogE("Failed eglMakeCurrent, error code:%x\n", eglGetError() ); return -1; } eglQuerySurface(env->egl.display, env->egl.surface, EGL_WIDTH, &env->egl.width); eglQuerySurface(env->egl.display, env->egl.surface, EGL_HEIGHT, &env->egl.height); Log("EGL Window Surface %d x %d\n", env->egl.width, env->egl.height); env->type = ON_SCREEN_RENDER; LOG_EXIT; return 0; }
/********************************************************************** * Initialize OpenGL ES and EGL ***********************************************************************/ static int engine_init_display(struct engine* engine) { /* * Here specify the attributes of the desired configuration. * Below, we select an EGLConfig with at least 8 bits per color * component compatible with on-screen windows */ const EGLint attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_NONE }; EGLint w, h, dummy, format; EGLint numConfigs; EGLConfig config; EGLSurface surface; EGLContext context; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0); /* Here, the application chooses the configuration it desires. In this * sample, we have a very simplified selection process, where we pick * the first EGLConfig that matches our criteria */ eglChooseConfig(display, attribs, &config, 1, &numConfigs); /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). * As soon as we picked a EGLConfig, we can safely reconfigure the * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format); surface = eglCreateWindowSurface(display, config, engine->app->window, NULL); EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribs); if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { LOGW("Unable to eglMakeCurrent"); return -1; } eglQuerySurface(display, surface, EGL_WIDTH, &w); eglQuerySurface(display, surface, EGL_HEIGHT, &h); engine->display = display; engine->context = context; engine->surface = surface; engine->width = w; engine->height = h; if(engine->app != NULL && engine->app->activity != NULL) { mgr = engine->app->activity->assetManager; } opengl_init(w,h); LOGI("opengl init"); return 0; }
// Sets the display, OpenGL|ES context and screen stuff static void opengl_init(void) { EGLBoolean result; EGLint num_config; static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; static const EGLint attribute_list[] = { EGL_DEPTH_SIZE, 16, //enable depth checking EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; EGLConfig config; // get an EGL display connection display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (display == EGL_NO_DISPLAY) { throw std::runtime_error("Failed to get display. eglGetDisplay failed."); } // initialize the EGL display connection result = eglInitialize(display, NULL, NULL); if (result == EGL_FALSE) { throw std::runtime_error("Failed to initialize display. eglInitialize failed."); } // get an appropriate EGL frame buffer configuration result = eglChooseConfig(display, attribute_list, &config, 1, &num_config); if (result == EGL_FALSE) { throw std::runtime_error("Failed to choose config. eglChooseConfig failed."); } // create an EGL rendering context context = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL); if (context == EGL_NO_CONTEXT) { throw std::runtime_error("Failed to create context. eglCreateContext failed."); } // create an EGL window surface int32_t success = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height); if (success < 0) { throw std::runtime_error("Failed to get display size."); } VC_RECT_T dst_rect = rect_width_height(screen_width, screen_height); VC_RECT_T src_rect = rect_width_height(screen_width<<16, screen_height<<16); dispman_display = vc_dispmanx_display_open(0 /* LCD */); dispman_update = vc_dispmanx_update_start(0); dispman_element = vc_dispmanx_element_add (dispman_update, dispman_display, 128/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, (DISPMANX_TRANSFORM_T)0/*transform*/); nativewindow.element = dispman_element; nativewindow.width = screen_width; nativewindow.height = screen_height; vc_dispmanx_update_submit_sync(dispman_update); surface = eglCreateWindowSurface(display, config, &nativewindow, NULL); if(surface == EGL_NO_SURFACE) { fprintf(stderr, "eglCreateWindowSurface returned ELG_NO_SURFACE. " "Try closing other OpenGL programs.\n"); exit(1); } // connect the context to the surface result = eglMakeCurrent(display, surface, surface, context); if (result == EGL_FALSE) { throw std::runtime_error("Failed to connect to the surface."); } glClearColor(0, 0, 0, 0); // set background colors glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear buffers glShadeModel(GL_FLAT); // Enable back face culling. glEnable(GL_CULL_FACE); }
/// // CreateEGLContext() // // Creates an EGL rendering context and all associated elements // EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay, EGLContext* eglContext, EGLSurface* eglSurface, EGLint attribList[]) { EGLint numConfigs; EGLint majorVersion; EGLint minorVersion; EGLDisplay display; EGLContext context; EGLSurface surface; EGLConfig config; #ifndef RPI_NO_X EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE }; #else EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; #endif // Get Display #ifndef RPI_NO_X display = eglGetDisplay((EGLNativeDisplayType)x_display); if ( display == EGL_NO_DISPLAY ) { return EGL_FALSE; } #else display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if ( display == EGL_NO_DISPLAY ) { return EGL_FALSE; } #endif // Initialize EGL if ( !eglInitialize(display, &majorVersion, &minorVersion) ) { return EGL_FALSE; } // Get configs if ( !eglGetConfigs(display, NULL, 0, &numConfigs) ) { return EGL_FALSE; } // Choose config if ( !eglChooseConfig(display, attribList, &config, 1, &numConfigs) ) { return EGL_FALSE; } // Create a surface surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)hWnd, NULL); if ( surface == EGL_NO_SURFACE ) { return EGL_FALSE; } // Create a GL context context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs ); if ( context == EGL_NO_CONTEXT ) { return EGL_FALSE; } // Make the context current if ( !eglMakeCurrent(display, surface, surface, context) ) { return EGL_FALSE; } *eglDisplay = display; *eglSurface = surface; *eglContext = context; return EGL_TRUE; }
void init_ogl(CUBE_STATE_T *state) { int32_t success = 0; EGLBoolean result; EGLint num_config; bcm_host_init(); static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; static const EGLint attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; static const EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLConfig config; // get an EGL display connection state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); // initialize the EGL display connection result = eglInitialize(state->display, NULL, NULL); // get an appropriate EGL frame buffer configuration result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config); assert(EGL_FALSE != result); // get an appropriate EGL frame buffer configuration result = eglBindAPI(EGL_OPENGL_ES_API); assert(EGL_FALSE != result); // create an EGL rendering context state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes); assert(state->context!=EGL_NO_CONTEXT); // create an EGL window surface success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height); assert( success >= 0 ); state->screen_width = 1024; state->screen_height = 1024; dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = state->screen_width; dst_rect.height = state->screen_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = state->screen_width << 16; src_rect.height = state->screen_height << 16; dispman_display = vc_dispmanx_display_open( 0 /* LCD */); dispman_update = vc_dispmanx_update_start( 0 ); dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/); nativewindow.element = dispman_element; nativewindow.width = state->screen_width; nativewindow.height = state->screen_height; vc_dispmanx_update_submit_sync( dispman_update ); state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL ); assert(state->surface != EGL_NO_SURFACE); // connect the context to the surface result = eglMakeCurrent(state->display, state->surface, state->surface, state->context); assert(EGL_FALSE != result); // Set background color and clear buffers glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Enable back face culling. //glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // glMatrixMode(GL_MODELVIEW); glViewport(0, 0, (GLsizei)state->screen_width, (GLsizei)state->screen_height); }
static EGLBoolean IJK_EGL_makeCurrent(IJK_EGL* egl, EGLNativeWindowType window) { if (window && window == egl->window && egl->display && egl->surface && egl->context) { if (!eglMakeCurrent(egl->display, egl->surface, egl->surface, egl->context)) { ALOGE("[EGL] elgMakeCurrent() failed (cached)\n"); return EGL_FALSE; } return EGL_TRUE; } IJK_EGL_terminate(egl); egl->window = window; if (!window) return EGL_FALSE; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (display == EGL_NO_DISPLAY) { ALOGE("[EGL] eglGetDisplay failed\n"); return EGL_FALSE; } EGLint major, minor; if (!eglInitialize(display, &major, &minor)) { ALOGE("[EGL] eglInitialize failed\n"); return EGL_FALSE; } ALOGI("[EGL] eglInitialize %d.%d\n", (int)major, (int)minor); static const EGLint configAttribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE }; static const EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLConfig config; EGLint numConfig; if (!eglChooseConfig(display, configAttribs, &config, 1, &numConfig)) { ALOGE("[EGL] eglChooseConfig failed\n"); eglTerminate(display); return EGL_FALSE; } #ifdef __ANDROID__ { EGLint native_visual_id = 0; if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &native_visual_id)) { ALOGE("[EGL] eglGetConfigAttrib() returned error %d", eglGetError()); eglTerminate(display); return EGL_FALSE; } int32_t width = ANativeWindow_getWidth(window); int32_t height = ANativeWindow_getWidth(window); ALOGI("[EGL] ANativeWindow_setBuffersGeometry(f=%d);", native_visual_id); int ret = ANativeWindow_setBuffersGeometry(window, width, height, native_visual_id); if (ret) { ALOGE("[EGL] ANativeWindow_setBuffersGeometry(format) returned error %d", ret); eglTerminate(display); return EGL_FALSE; } } #endif EGLSurface surface = eglCreateWindowSurface(display, config, window, NULL); if (surface == EGL_NO_SURFACE) { ALOGE("[EGL] eglCreateWindowSurface failed\n"); eglTerminate(display); return EGL_FALSE; } EGLSurface context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs); if (context == EGL_NO_CONTEXT) { ALOGE("[EGL] eglCreateContext failed\n"); eglDestroySurface(display, surface); eglTerminate(display); return EGL_FALSE; } if (!eglMakeCurrent(display, surface, surface, context)) { ALOGE("[EGL] elgMakeCurrent() failed (new)\n"); eglDestroyContext(display, context); eglDestroySurface(display, surface); eglTerminate(display); return EGL_FALSE; } #if 0 #if defined(__ANDROID__) { const char *extensions = (const char *) glGetString(GL_EXTENSIONS); if (extensions) { char *dup_extensions = strdup(extensions); if (dup_extensions) { char *brk = NULL; char *ext = strtok_r(dup_extensions, " ", &brk); while (ext) { if (0 == strcmp(ext, "GL_EXT_texture_rg")) egl->gles2_extensions[IJK_GLES2__GL_EXT_texture_rg] = 1; ext = strtok_r(NULL, " ", &brk); } free(dup_extensions); } } } #elif defined(__APPLE__) egl->gles2_extensions[IJK_GLES2__GL_EXT_texture_rg] = 1; #endif ALOGI("[EGL] GLES2 extensions begin:\n"); ALOGI("[EGL] GL_EXT_texture_rg: %d\n", egl->gles2_extensions[IJK_GLES2__GL_EXT_texture_rg]); ALOGI("[EGL] GLES2 extensions end.\n"); #endif IJK_GLES2_Renderer_setupGLES(); egl->context = context; egl->surface = surface; egl->display = display; return EGL_TRUE; }
int main(int argc, char *argv[]) { EGLint egl_major, egl_minor; EGLConfig config; EGLint num_config; EGLContext context; GLuint vertex_shader; GLuint fragment_shader; GLuint program; GLint ret; GLint width, height; #ifdef USE_X XDisplay = XOpenDisplay(NULL); if (!XDisplay) { fprintf(stderr, "Error: failed to open X display.\n"); return -1; } Window XRoot = DefaultRootWindow(XDisplay); XSetWindowAttributes XWinAttr; XWinAttr.event_mask = ExposureMask | PointerMotionMask; XWindow = XCreateWindow(XDisplay, XRoot, 0, 0, WIDTH, HEIGHT, 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask, &XWinAttr); XMapWindow(XDisplay, XWindow); XStoreName(XDisplay, XWindow, "Mali libs test"); egl_display = eglGetDisplay((EGLNativeDisplayType) XDisplay); #else egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); #endif /* USE_X */ if (egl_display == EGL_NO_DISPLAY) { fprintf(stderr, "Error: No display found!\n"); return -1; } if (!eglInitialize(egl_display, &egl_major, &egl_minor)) { fprintf(stderr, "Error: eglInitialise failed!\n"); return -1; } printf("EGL Version: \"%s\"\n", eglQueryString(egl_display, EGL_VERSION)); printf("EGL Vendor: \"%s\"\n", eglQueryString(egl_display, EGL_VENDOR)); printf("EGL Extensions: \"%s\"\n", eglQueryString(egl_display, EGL_EXTENSIONS)); eglChooseConfig(egl_display, config_attribute_list, &config, 1, &num_config); context = eglCreateContext(egl_display, config, EGL_NO_CONTEXT, context_attribute_list); if (context == EGL_NO_CONTEXT) { fprintf(stderr, "Error: eglCreateContext failed: 0x%08X\n", eglGetError()); return -1; } #ifdef USE_X egl_surface = eglCreateWindowSurface(egl_display, config, (void *) XWindow, window_attribute_list); #else egl_surface = eglCreateWindowSurface(egl_display, config, &native_window, window_attribute_list); #endif if (egl_surface == EGL_NO_SURFACE) { fprintf(stderr, "Error: eglCreateWindowSurface failed: " "0x%08X\n", eglGetError()); return -1; } if (!eglQuerySurface(egl_display, egl_surface, EGL_WIDTH, &width) || !eglQuerySurface(egl_display, egl_surface, EGL_HEIGHT, &height)) { fprintf(stderr, "Error: eglQuerySurface failed: 0x%08X\n", eglGetError()); return -1; } printf("Surface size: %dx%d\n", width, height); if (!eglMakeCurrent(egl_display, egl_surface, egl_surface, context)) { fprintf(stderr, "Error: eglMakeCurrent() failed: 0x%08X\n", eglGetError()); return -1; } printf("GL Vendor: \"%s\"\n", glGetString(GL_VENDOR)); printf("GL Renderer: \"%s\"\n", glGetString(GL_RENDERER)); printf("GL Version: \"%s\"\n", glGetString(GL_VERSION)); printf("GL Extensions: \"%s\"\n", glGetString(GL_EXTENSIONS)); printf("\nNow you should see the animation with 1 FPS framerate\n"); printf("of the screen changing background color between yellow\n"); printf("and blue (starting with yellow). Based on the timing\n"); printf("of going fullscreen, it may expose xf86-video-mali bug.\n"); set_fullscreen(); Redraw(width, height); #ifdef USE_X while (1) { Redraw(width, height); } #endif return 0; }
bool EGLView::initGL() { EGLint eglConfigCount; EGLConfig config; // Hard-coded to 32-bit/OpenGL ES 2.0. const EGLint eglConfigAttrs[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; const EGLint eglContextAttrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; const EGLint eglSurfaceAttrs[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE }; // Get the EGL display and initialize. _eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (_eglDisplay == EGL_NO_DISPLAY) { perror("eglGetDisplay"); return false; } if (eglInitialize(_eglDisplay, NULL, NULL) != EGL_TRUE) { perror("eglInitialize"); return false; } if (eglChooseConfig(_eglDisplay, eglConfigAttrs, &config, 1, &eglConfigCount) != EGL_TRUE || eglConfigCount == 0) { checkErrorEGL("eglChooseConfig"); return false; } _eglContext = eglCreateContext(_eglDisplay, config, EGL_NO_CONTEXT, eglContextAttrs); if (_eglContext == EGL_NO_CONTEXT) { checkErrorEGL("eglCreateContext"); return false; } _eglSurface = eglCreateWindowSurface(_eglDisplay, config, NULL, eglSurfaceAttrs); if (_eglSurface == EGL_NO_SURFACE) { checkErrorEGL("eglCreateWindowSurface"); return false; } if (eglMakeCurrent(_eglDisplay, _eglSurface, _eglSurface, _eglContext) != EGL_TRUE) { checkErrorEGL("eglMakeCurrent"); return false; } // FIXME: Get the actual canvas size somehow. EGLint width; EGLint height; if ((_eglDisplay == EGL_NO_DISPLAY) || (_eglSurface == EGL_NO_SURFACE) ) return EXIT_FAILURE; eglQuerySurface(_eglDisplay, _eglSurface, EGL_WIDTH, &width); eglQuerySurface(_eglDisplay, _eglSurface, EGL_HEIGHT, &height); _screenSize.width = width; _screenSize.height = height; glViewport(0, 0, width, height); // Default the frame size to be the whole canvas. In general we want to be // setting the size of the viewport by adjusting the canvas size (so // there's no weird letterboxing). setFrameSize(width, height); return true; }
Platform* Platform::create(Game* game, void* attachToWindow) { FileSystem::setResourcePath("./app/native/"); Platform* platform = new Platform(game); // Query game config int samples = 0; Properties* config = Game::getInstance()->getConfig()->getNamespace("window", true); if (config) { samples = std::max(config->getInt("samples"), 0); } __gestureSet = gestures_set_alloc(); swipe_gesture_alloc(NULL, gesture_callback, __gestureSet); pinch_gesture_alloc(NULL, gesture_callback, __gestureSet); tap_gesture_alloc(NULL, gesture_callback, __gestureSet); bps_initialize(); // Initialize navigator and orientation static const int SENSOR_RATE = 25000; sensor_set_rate(SENSOR_TYPE_AZIMUTH_PITCH_ROLL, SENSOR_RATE); sensor_set_skip_duplicates(SENSOR_TYPE_AZIMUTH_PITCH_ROLL, true); sensor_request_events(SENSOR_TYPE_AZIMUTH_PITCH_ROLL); navigator_request_events(0); navigator_rotation_lock(true); __orientationAngle = atoi(getenv("ORIENTATION")); int rc = 0; int screenFormat = SCREEN_FORMAT_RGBA8888; #ifdef __X86__ int screenUsage = SCREEN_USAGE_OPENGL_ES2; #else int screenUsage = SCREEN_USAGE_DISPLAY|SCREEN_USAGE_OPENGL_ES2; // Physical device copy directly into physical display #endif int screenSwapInterval = WINDOW_VSYNC ? 1 : 0; int screenTransparency = SCREEN_TRANSPARENCY_NONE; char *width_str = getenv("WIDTH"); char *height_str = getenv("HEIGHT"); // Hard-coded to (0,0). int windowPosition[] = { 0, 0 }; EGLint eglConfigCount; // Hard-coded to 32-bit/OpenGL ES 2.0. // NOTE: EGL_SAMPLE_BUFFERS and EGL_SAMPLES MUST remain at the beginning of the attribute list // since they are expected to be at indices 0-3 in config fallback code later. EGLint eglConfigAttrs[] = { EGL_SAMPLE_BUFFERS, samples > 0 ? 1 : 0, EGL_SAMPLES, samples, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; const EGLint eglContextAttrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; const EGLint eglSurfaceAttrs[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE }; // Create the screen context. rc = screen_create_context(&__screenContext, 0); if (rc) { perror("screen_create_context"); goto error; } // Create the screen window. rc = screen_create_window(&__screenWindow, __screenContext); if (rc) { perror("screen_create_window"); goto error; } // Set/get any window properties. rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_FORMAT, &screenFormat); if (rc) { perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)"); goto error; } rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_USAGE, &screenUsage); if (rc) { perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)"); goto error; } if (width_str && height_str) { __screenWindowSize[0] = atoi(width_str); __screenWindowSize[1] = atoi(height_str); } else { screen_display_t screen_display; rc = screen_get_window_property_pv(__screenWindow, SCREEN_PROPERTY_DISPLAY, (void **)&screen_display); if (rc) { perror("screen_get_window_property_pv(SCREEN_PROPERTY_DISPLAY)"); goto error; } screen_display_mode_t screen_mode; rc = screen_get_display_property_pv(screen_display, SCREEN_PROPERTY_MODE, (void**)&screen_mode); if (rc) { perror("screen_get_display_property_pv(SCREEN_PROPERTY_MODE)"); goto error; } int size[2]; rc = screen_get_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, size); if (rc) { perror("screen_get_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)"); goto error; } __screenWindowSize[0] = size[0]; __screenWindowSize[1] = size[1]; if ((__orientationAngle == 0) || (__orientationAngle == 180)) { if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) || ((screen_mode.width < screen_mode.height) && (size[0] > size[1]))) { __screenWindowSize[1] = size[0]; __screenWindowSize[0] = size[1]; } } else if ((__orientationAngle == 90) || (__orientationAngle == 270)) { if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) || ((screen_mode.width < screen_mode.height) && (size[0] < size[1]))) { __screenWindowSize[1] = size[0]; __screenWindowSize[0] = size[1]; } } else { perror("Navigator returned an unexpected orientation angle."); goto error; } rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_ROTATION, &__orientationAngle); if (rc) { perror("screen_set_window_property_iv(SCREEN_PROPERTY_ROTATION)"); goto error; } } rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_BUFFER_SIZE, __screenWindowSize); if (rc) { perror("screen_set_window_property_iv(SCREEN_PROPERTY_BUFFER_SIZE)"); goto error; } if (windowPosition[0] != 0 || windowPosition[1] != 0) { rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_POSITION, windowPosition); if (rc) { perror("screen_set_window_property_iv(SCREEN_PROPERTY_POSITION)"); goto error; } } rc = screen_set_window_property_iv(__screenWindow, SCREEN_PROPERTY_TRANSPARENCY, &screenTransparency); if (rc) { perror("screen_set_window_property_iv(SCREEN_PROPERTY_TRANSPARENCY)"); goto error; } // Double buffered. rc = screen_create_window_buffers(__screenWindow, 2); if (rc) { perror("screen_create_window_buffers"); goto error; } // Create screen event object. rc = screen_create_event(&__screenEvent); if (rc) { perror("screen_create_event"); goto error; } // Request screen events. screen_request_events(__screenContext); // Get the EGL display and initialize. __eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (__eglDisplay == EGL_NO_DISPLAY) { perror("eglGetDisplay"); goto error; } if (eglInitialize(__eglDisplay, NULL, NULL) != EGL_TRUE) { perror("eglInitialize"); goto error; } if (eglChooseConfig(__eglDisplay, eglConfigAttrs, &__eglConfig, 1, &eglConfigCount) != EGL_TRUE || eglConfigCount == 0) { bool success = false; while (samples) { // Try lowering the MSAA sample count until we find a supported config GP_WARN("Failed to find a valid EGL configuration with EGL samples=%d. Trying samples=%d instead.", samples, samples/2); samples /= 2; eglConfigAttrs[1] = samples > 0 ? 1 : 0; eglConfigAttrs[3] = samples; if (eglChooseConfig(__eglDisplay, eglConfigAttrs, &__eglConfig, 1, &eglConfigCount) == EGL_TRUE && eglConfigCount > 0) { success = true; break; } } if (!success) { checkErrorEGL("eglChooseConfig"); goto error; } } __eglContext = eglCreateContext(__eglDisplay, __eglConfig, EGL_NO_CONTEXT, eglContextAttrs); if (__eglContext == EGL_NO_CONTEXT) { checkErrorEGL("eglCreateContext"); goto error; } __eglSurface = eglCreateWindowSurface(__eglDisplay, __eglConfig, __screenWindow, eglSurfaceAttrs); if (__eglSurface == EGL_NO_SURFACE) { checkErrorEGL("eglCreateWindowSurface"); goto error; } if (eglMakeCurrent(__eglDisplay, __eglSurface, __eglSurface, __eglContext) != EGL_TRUE) { checkErrorEGL("eglMakeCurrent"); goto error; } // Set vsync. eglSwapInterval(__eglDisplay, screenSwapInterval); // Initialize OpenGL ES extensions. __glExtensions = (const char*)glGetString(GL_EXTENSIONS); if (strstr(__glExtensions, "GL_OES_vertex_array_object") || strstr(__glExtensions, "GL_ARB_vertex_array_object")) { glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES"); glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES"); glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES"); glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES"); } return platform; error: // TODO: cleanup return NULL; }
// oglinit sets the display, OpenGL|ES context and screen information // state holds the OGLES model information extern void oglinit(STATE_T * state) { int32_t success = 0; EGLBoolean result; EGLint num_config; static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; static const EGLint attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; EGLConfig config; // get an EGL display connection state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); assert(state->display != EGL_NO_DISPLAY); // initialize the EGL display connection result = eglInitialize(state->display, NULL, NULL); assert(EGL_FALSE != result); // bind OpenVG API eglBindAPI(EGL_OPENVG_API); // get an appropriate EGL frame buffer configuration result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config); assert(EGL_FALSE != result); // create an EGL rendering context state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL); assert(state->context != EGL_NO_CONTEXT); // create an EGL window surface success = graphics_get_display_size(0 /* LCD */ , &state->screen_width, &state->screen_height); assert(success >= 0); dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = state->screen_width; dst_rect.height = state->screen_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = state->screen_width << 16; src_rect.height = state->screen_height << 16; dispman_display = vc_dispmanx_display_open(0 /* LCD */ ); dispman_update = vc_dispmanx_update_start(0); dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display, 0 /*layer */ , &dst_rect, 0 /*src */ , &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha */ , 0 /*clamp */ , 0 /*transform */ ); nativewindow.element = dispman_element; nativewindow.width = state->screen_width; nativewindow.height = state->screen_height; vc_dispmanx_update_submit_sync(dispman_update); state->surface = eglCreateWindowSurface(state->display, config, &nativewindow, NULL); assert(state->surface != EGL_NO_SURFACE); // preserve the buffers on swap result = eglSurfaceAttrib(state->display, state->surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); assert(EGL_FALSE != result); // connect the context to the surface result = eglMakeCurrent(state->display, state->surface, state->surface, state->context); assert(EGL_FALSE != result); // set up screen ratio glViewport(0, 0, (GLsizei) state->screen_width, (GLsizei) state->screen_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float ratio = (float)state->screen_width / (float)state->screen_height; glFrustumf(-ratio, ratio, -1.0f, 1.0f, 1.0f, 10.0f); }
int glwtInitEGL(const GLWTConfig *config) { int config_attribs[] = { EGL_RED_SIZE, config ? config->red_bits : 0, EGL_GREEN_SIZE, config ? config->green_bits : 0, EGL_BLUE_SIZE, config ? config->blue_bits : 0, EGL_ALPHA_SIZE, config ? config->alpha_bits : 0, EGL_DEPTH_SIZE, config ? config->depth_bits : 0, EGL_STENCIL_SIZE, config ? config->stencil_bits : 0, EGL_SAMPLES, config ? config->samples : 0, EGL_SAMPLE_BUFFERS, config ? config->sample_buffers : 0, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, (!config || (config->api & GLWT_API_MASK) == GLWT_API_ANY || ((config->api & GLWT_API_MASK) == GLWT_API_OPENGL_ES && (config->api_version_major == 0 || config->api_version_major == 2))) ? EGL_OPENGL_ES2_BIT : (config && (config->api & GLWT_API_MASK) == GLWT_API_OPENGL_ES && config->api_version_major == 1) ? EGL_OPENGL_ES_BIT : (config && (config->api & GLWT_API_MASK) == GLWT_API_OPENGL) ? EGL_OPENGL_BIT : 0, EGL_NONE }; int num_configs; if(glxwInitEGL() != 0) { glwtErrorPrintf("Initializing EGL extensions failed"); return -1; } glwt.api = config ? config->api : GLWT_API_OPENGL_ES; glwt.api_version_major = config ? config->api_version_major : 2; glwt.api_version_minor = config ? config->api_version_minor : 0; if(!glwt.egl.display) { glwt.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if(!glwt.egl.display) { glwtErrorPrintf("eglGetDisplay failed"); goto error; } } if(!eglInitialize(glwt.egl.display, &glwt.egl.version_major, &glwt.egl.version_minor)) { glwtErrorPrintf("EGL initialization failed"); return -1; } if(!eglChooseConfig(glwt.egl.display, config_attribs, &glwt.egl.config, 1, &num_configs) || num_configs != 1) { glwtErrorPrintf("eglChooseConfig failed"); goto error; } if(!eglGetConfigAttrib(glwt.egl.display, glwt.egl.config, EGL_NATIVE_VISUAL_ID, &glwt.egl.visual_id)) { glwtErrorPrintf("eglGetConfigAttrib failed"); goto error; } return 0; error: glwtQuitEGL(); return -1; }
EGLContext EGLDisplayOpenVG::contextForSurface(const EGLSurface& surface) { ASSERT(surface != EGL_NO_SURFACE); if (m_platformSurfaces.contains(surface)) return m_platformSurfaces.get(surface)->eglContext(); eglBindAPI(EGL_OPENVG_API); ASSERT_EGL_NO_ERROR(); EGLint surfaceConfigId; if (m_surfaceConfigIds.contains(surface)) surfaceConfigId = m_surfaceConfigIds.get(surface); else { // Retrieve the same EGL config for context creation that was used to // create the the EGL surface. EGLBoolean success = eglQuerySurface(m_display, surface, EGL_CONFIG_ID, &surfaceConfigId); ASSERT(success == EGL_TRUE); ASSERT(surfaceConfigId != EGL_BAD_ATTRIBUTE); m_surfaceConfigIds.set(surface, surfaceConfigId); } if (m_compatibleConfigIds.contains(surfaceConfigId)) surfaceConfigId = m_compatibleConfigIds.get(surfaceConfigId); if (m_contexts.contains(surfaceConfigId)) return m_contexts.get(surfaceConfigId); if (!m_sharedPlatformSurface) // shared context has not been created yet sharedPlatformSurface(); // creates the shared surface & context EGLDisplay currentDisplay = eglGetCurrentDisplay(); EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ); EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW); EGLContext currentContext = eglGetCurrentContext(); // Before creating a new context, let's try whether an existing one // is compatible with the surface. EGL doesn't give us a different way // to check context/surface compatibility than trying it out, so let's // do just that. HashMap<EGLint, EGLContext>::iterator end = m_contexts.end(); for (HashMap<EGLint, EGLContext>::iterator it = m_contexts.begin(); it != end; ++it) { eglMakeCurrent(m_display, surface, surface, (*it).second); if (eglGetError() == EGL_SUCCESS) { // Restore previous surface/context. if (currentContext != EGL_NO_CONTEXT) { eglMakeCurrent(currentDisplay, currentReadSurface, currentDrawSurface, currentContext); ASSERT_EGL_NO_ERROR(); } // Cool, surface is compatible to one of our existing contexts. m_compatibleConfigIds.set(surfaceConfigId, (*it).first); return (*it).second; } } // Restore previous surface/context. if (currentContext != EGL_NO_CONTEXT) { eglMakeCurrent(currentDisplay, currentReadSurface, currentDrawSurface, currentContext); ASSERT_EGL_NO_ERROR(); } EGLConfig config; EGLint numConfigs; const EGLint configAttribs[] = { EGL_CONFIG_ID, surfaceConfigId, EGL_NONE }; eglChooseConfig(m_display, configAttribs, &config, 1, &numConfigs); ASSERT_EGL_NO_ERROR(); ASSERT(numConfigs == 1); // We share all of the images and paths amongst the different contexts, // so that they can be used in all of them. Resources that are created // while m_sharedPlatformSurface->context() is current will be // accessible from all other contexts, but are not restricted to the // lifetime of those contexts. EGLContext context = eglCreateContext(m_display, config, m_sharedPlatformSurface->eglContext(), 0); ASSERT_EGL_NO_ERROR(); ASSERT(!m_contexts.contains(surfaceConfigId)); m_contexts.set(surfaceConfigId, context); return context; }
static int egl_create_context(struct vo_wayland_state *wl, MPGLContext *ctx, bool enable_alpha) { EGLint major, minor, n; GL *gl = ctx->gl; const char *eglstr = ""; if (!(wl->egl_context.egl.dpy = eglGetDisplay(wl->display.display))) return -1; EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_ALPHA_SIZE, enable_alpha, EGL_DEPTH_SIZE, 1, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE }; /* major and minor here returns the supported EGL version (e.g.: 1.4) */ if (eglInitialize(wl->egl_context.egl.dpy, &major, &minor) != EGL_TRUE) return -1; MP_VERBOSE(wl, "EGL version %d.%d\n", major, minor); EGLint context_attribs[] = { // aka EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE }; if (eglBindAPI(EGL_OPENGL_API) != EGL_TRUE) return -1; eglChooseConfig(wl->egl_context.egl.dpy, config_attribs, &wl->egl_context.egl.conf, 1, &n); wl->egl_context.egl.ctx = eglCreateContext(wl->egl_context.egl.dpy, wl->egl_context.egl.conf, EGL_NO_CONTEXT, context_attribs); if (!wl->egl_context.egl.ctx) { /* fallback to any GL version */ MP_WARN(wl, "can't create context for requested OpenGL version: " "fall back to any version available\n"); context_attribs[0] = EGL_NONE; wl->egl_context.egl.ctx = eglCreateContext(wl->egl_context.egl.dpy, wl->egl_context.egl.conf, EGL_NO_CONTEXT, context_attribs); if (!wl->egl_context.egl.ctx) return -1; } eglMakeCurrent(wl->egl_context.egl.dpy, NULL, NULL, wl->egl_context.egl.ctx); eglstr = eglQueryString(wl->egl_context.egl.dpy, EGL_EXTENSIONS); mpgl_load_functions(gl, (void*(*)(const GLubyte*))eglGetProcAddress, eglstr, wl->log); ctx->native_display_type = "wl"; ctx->native_display = wl->display.display; return 0; }
EGLBoolean GLUSAPIENTRY glusEGLCreateContext(EGLNativeDisplayType eglNativeDisplayType, EGLDisplay* eglDisplay, EGLConfig* eglConfig, EGLContext *eglContext, const EGLint attribList[], const EGLint eglContextClientVersion) { EGLint numConfigs; EGLint majorVersion; EGLint minorVersion; EGLDisplay display = EGL_NO_DISPLAY; EGLConfig config = 0; EGLDisplay context = EGL_NO_CONTEXT; EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, GLUS_DEFAULT_CLIENT_VERSION, EGL_NONE, EGL_NONE }; if (!eglDisplay || !eglConfig || !eglContext) { glusLogPrint(GLUS_LOG_ERROR, "No eglDisplay, eglConfig or eglContext passed"); return EGL_FALSE; } // Get Display display = eglGetDisplay((EGLNativeDisplayType) eglNativeDisplayType); if (display == EGL_NO_DISPLAY) { glusLogPrint(GLUS_LOG_ERROR, "Could not get EGL display"); return EGL_FALSE; } // Initialize EGL if (!eglInitialize(display, &majorVersion, &minorVersion)) { glusLogPrint(GLUS_LOG_ERROR, "Could not initialize EGL"); glusEGLTerminate(display, 0, 0); return EGL_FALSE; } glusLogPrint(GLUS_LOG_INFO, "EGL version: %d.%d", majorVersion, minorVersion); // Choose config if (!eglChooseConfig(display, attribList, &config, 1, &numConfigs)) { glusLogPrint(GLUS_LOG_ERROR, "Could not choose EGL configuration"); glusEGLTerminate(display, 0, 0); return EGL_FALSE; } if (numConfigs == 0) { glusLogPrint(GLUS_LOG_ERROR, "Could no EGL configuration returned"); glusEGLTerminate(display, 0, 0); return EGL_FALSE; } contextAttribs[1] = eglContextClientVersion; // Create a GL ES context context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs); if (context == EGL_NO_CONTEXT) { glusLogPrint(GLUS_LOG_ERROR, "Could not create EGL context. EGL context client version: %d", eglContextClientVersion); glusEGLTerminate(eglDisplay, 0, 0); return EGL_FALSE; } glusLogPrint(GLUS_LOG_INFO, "EGL context client version: %d", eglContextClientVersion); *eglDisplay = display; *eglConfig = config; *eglContext = context; return EGL_TRUE; }
static bool android_gfx_ctx_init(void *data) { int var; EGLint num_config, egl_version_major, egl_version_minor; EGLint format; EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, g_es3 ? 3 : 2, EGL_NONE }; const EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE }; driver_t *driver = driver_get_ptr(); gfx_ctx_android_data_t *android = NULL; struct android_app *android_app = (struct android_app*)g_android; if (!android_app) return false; android = (gfx_ctx_android_data_t*) calloc(1, sizeof(gfx_ctx_android_data_t)); if (!android) return false; RARCH_LOG("Android EGL: GLES version = %d.\n", g_es3 ? 3 : 2); android->g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!android->g_egl_dpy) { RARCH_ERR("[Android/EGL]: Couldn't get EGL display.\n"); goto error; } if (!eglInitialize(android->g_egl_dpy, &egl_version_major, &egl_version_minor)) goto error; RARCH_LOG("[ANDROID/EGL]: EGL version: %d.%d\n", egl_version_major, egl_version_minor); if (!eglChooseConfig(android->g_egl_dpy, attribs, &android->g_egl_config, 1, &num_config)) goto error; var = eglGetConfigAttrib(android->g_egl_dpy, android->g_egl_config, EGL_NATIVE_VISUAL_ID, &format); if (!var) { RARCH_ERR("eglGetConfigAttrib failed: %d.\n", var); goto error; } ANativeWindow_setBuffersGeometry(android_app->window, 0, 0, format); android->g_egl_ctx = eglCreateContext(android->g_egl_dpy, android->g_egl_config, EGL_NO_CONTEXT, context_attributes); if (android->g_egl_ctx == EGL_NO_CONTEXT) goto error; if (android->g_use_hw_ctx) { android->g_egl_hw_ctx = eglCreateContext(android->g_egl_dpy, android->g_egl_config, android->g_egl_ctx, context_attributes); RARCH_LOG("[Android/EGL]: Created shared context: %p.\n", (void*)android->g_egl_hw_ctx); if (android->g_egl_hw_ctx == EGL_NO_CONTEXT) goto error; } android->g_egl_surf = eglCreateWindowSurface(android->g_egl_dpy, android->g_egl_config, android_app->window, 0); if (!android->g_egl_surf) goto error; if (!eglMakeCurrent(android->g_egl_dpy, android->g_egl_surf, android->g_egl_surf, android->g_egl_ctx)) goto error; driver->video_context_data = android; return true; error: android_gfx_ctx_destroy_resources(android); if (android) free(android); return false; }
/*********************************************************** * Name: init_egl * * Arguments: * CUBE_STATE_T *state - holds OGLES model info * * Description: Sets the display, OpenGL|ES context and screen stuff * * Returns: void * ***********************************************************/ static void init_egl(void) { int32_t success = 0; EGLBoolean result; EGLint num_config; static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_ELEMENT_HANDLE_T dispman_element; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; static const EGLint attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; static EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; EGLConfig config; // get an EGL display connection state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); assert(state->display!=EGL_NO_DISPLAY); // initialize the EGL display connection result = eglInitialize(state->display, NULL, NULL); assert(EGL_FALSE != result); // get an appropriate EGL frame buffer configuration result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config); assert(EGL_FALSE != result); // bind the gles api to this thread - this is default so not required result = eglBindAPI(EGL_OPENGL_ES_API); assert(EGL_FALSE != result); // create an EGL rendering context // select es 1.x or 2.x based on user option context_attributes[1] = state->useGLES2 + 1; state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes); assert(state->context!=EGL_NO_CONTEXT); // create an EGL window surface success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height); assert( success >= 0 ); dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = state->screen_width; dst_rect.height = state->screen_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = state->screen_width << 16; src_rect.height = state->screen_height << 16; dispman_display = vc_dispmanx_display_open( 0 /* LCD */); dispman_update = vc_dispmanx_update_start( 0 ); dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/); nativewindow.element = dispman_element; nativewindow.width = state->screen_width; nativewindow.height = state->screen_height; vc_dispmanx_update_submit_sync( dispman_update ); state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL ); assert(state->surface != EGL_NO_SURFACE); // connect the context to the surface result = eglMakeCurrent(state->display, state->surface, state->surface, state->context); assert(EGL_FALSE != result); // default to no vertical sync but user option may turn it on result = eglSwapInterval(state->display, state->useVSync ); assert(EGL_FALSE != result); // Set background color and clear buffers glClearColor(0.25f, 0.45f, 0.55f, 1.0f); // Enable back face culling. glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); if (state->wantInfo) { printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); } }
/*********************************************************** * Name: init_ogl * * Arguments: * APP_STATE_T *state - holds OGLES model info * * Description: Sets the display, OpenGL|ES context and screen stuff * * Returns: void * ***********************************************************/ static void init_ogl (APP_STATE_T * state) { int32_t success = 0; EGLBoolean result; EGLint num_config; EGLNativeWindowType window_handle = (EGLNativeWindowType) 0; #if defined (USE_OMX_TARGET_RPI) static EGL_DISPMANX_WINDOW_T nativewindow; DISPMANX_UPDATE_HANDLE_T dispman_update; VC_RECT_T dst_rect; VC_RECT_T src_rect; VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, 0 }; #endif static const EGLint attribute_list[] = { EGL_DEPTH_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; static const EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLConfig config; /* get an EGL display connection */ state->display = eglGetDisplay (EGL_DEFAULT_DISPLAY); assert (state->display != EGL_NO_DISPLAY); /* initialize the EGL display connection */ result = eglInitialize (state->display, NULL, NULL); assert (EGL_FALSE != result); #if defined (USE_OMX_TARGET_RPI) /* get an appropriate EGL frame buffer configuration * this uses a BRCM extension that gets the closest match, rather * than standard which returns anything that matches. */ result = eglSaneChooseConfigBRCM (state->display, attribute_list, &config, 1, &num_config); assert (EGL_FALSE != result); #else result = eglChooseConfig (state->display, attribute_list, &config, 1, &num_config); #endif /* create an EGL rendering context */ state->context = eglCreateContext (state->display, config, EGL_NO_CONTEXT, context_attributes); assert (state->context != EGL_NO_CONTEXT); #if defined (USE_OMX_TARGET_RPI) /* create an EGL window surface */ success = graphics_get_display_size (0 /* LCD */ , &state->screen_width, &state->screen_height); assert (success >= 0); dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = state->screen_width; dst_rect.height = state->screen_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = state->screen_width << 16; src_rect.height = state->screen_height << 16; state->dispman_display = vc_dispmanx_display_open (0 /* LCD */ ); dispman_update = vc_dispmanx_update_start (0); state->dispman_element = vc_dispmanx_element_add (dispman_update, state->dispman_display, 0 /*layer */ , &dst_rect, 0 /*src */ , &src_rect, DISPMANX_PROTECTION_NONE, &alpha, 0 /*clamp */ , 0 /*transform */ ); nativewindow.element = state->dispman_element; nativewindow.width = state->screen_width; nativewindow.height = state->screen_height; vc_dispmanx_update_submit_sync (dispman_update); window_handle = &nativewindow; #endif state->surface = eglCreateWindowSurface (state->display, config, window_handle, NULL); assert (state->surface != EGL_NO_SURFACE); /* connect the context to the surface */ result = eglMakeCurrent (state->display, state->surface, state->surface, state->context); assert (EGL_FALSE != result); }
/** * Initialize the default EGL * Create a Pbuffer Surface for off-screen render */ static int initDefaultEGL(SdkEnv *env) { VALIDATE_NOT_NULL(env); env->egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (EGL_NO_DISPLAY == env->egl.display || EGL_SUCCESS != eglGetError()) { LogE("Failed eglGetDisplay\n"); return -1; } EGLint major, minor; if (!eglInitialize(env->egl.display, &major, &minor) || EGL_SUCCESS != eglGetError()) { LogE("Failed eglInitialize\n"); return -1; } Log("EGL %d.%d\n", major, minor); EGLConfig configs[2]; EGLint numConfigs; if (eglGetConfigs(env->egl.display, configs, 2, &numConfigs) == EGL_FALSE || EGL_SUCCESS != eglGetError()) { LogE("Failed eglGetConfigs\n"); return -1; } EGLint cfg_attrs[] = { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE }; if (!eglChooseConfig(env->egl.display, cfg_attrs, configs, 2, &numConfigs) || numConfigs < 1) { LogE("Failed eglChooseConfig\n"); return -1; } #define SURFACE_MAX_WIDTH 2048 #define SURFACE_MAX_HEIGHT 2048 EGLint surface_attrs[] = { EGL_WIDTH, SURFACE_MAX_WIDTH, EGL_HEIGHT, SURFACE_MAX_HEIGHT, /* EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGAB, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, */ EGL_LARGEST_PBUFFER, EGL_TRUE, EGL_NONE }; env->egl.surface = eglCreatePbufferSurface(env->egl.display, configs[0], surface_attrs); if (EGL_NO_SURFACE == env->egl.surface) { LogE("Failed create Pbuffer Surface, error code:%x\n", eglGetError()); return -1; } if (!eglBindAPI(EGL_OPENGL_ES_API)) { LogE("Failed eglBindAPI\n"); return -1; } EGLint context_attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; env->egl.context = eglCreateContext(env->egl.display, configs[0], EGL_NO_CONTEXT, context_attrs); if (EGL_NO_CONTEXT == env->egl.context) { LogE("Failed create context, error code:%x\n", eglGetError() ); return -1; } if (!eglMakeCurrent(env->egl.display, env->egl.surface, env->egl.surface, env->egl.context)) { LogE("Failed eglMakeCurrent, error code:%x\n", eglGetError() ); return -1; } eglQuerySurface(env->egl.display, env->egl.surface, EGL_WIDTH, &env->egl.width); eglQuerySurface(env->egl.display, env->egl.surface, EGL_HEIGHT, &env->egl.height); Log("EGL Pbuffer Surface %d x %d\n", env->egl.width, env->egl.height); env->type = OFF_SCREEN_RENDER; return 0; }
bool cInterfaceEGL::ChooseAndCreate(void *window_handle, bool core, bool use565) { int attribs32[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_TRANSPARENT_TYPE, EGL_NONE, EGL_NONE, 0 }; int attribs16[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_TRANSPARENT_TYPE, EGL_NONE, EGL_NONE, 0 }; int attribsFallback32[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_NONE, 0 }; int attribsFallback16[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Keep this first! EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_DEPTH_SIZE, 16, EGL_NONE, 0 }; int *attribs = attribs32; int *attribsFallback = attribsFallback32; if (use565) { attribs = attribs16; attribsFallback = attribsFallback16; } EGLint ctx_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, 0 }; switch (s_opengl_mode) { case MODE_OPENGL: EGL_ILOG("Setting RENDERABLE_TYPE to EGL_OPENGL_BIT"); attribs[1] = EGL_OPENGL_BIT; ctx_attribs[0] = EGL_NONE; break; case MODE_OPENGLES2: EGL_ILOG("Setting RENDERABLE_TYPE to EGL_OPENGL_ES2_BIT"); attribs[1] = EGL_OPENGL_ES2_BIT; ctx_attribs[1] = 2; break; case MODE_OPENGLES3: EGL_ILOG("Setting RENDERABLE_TYPE to EGL_OPENGL_ES3_BIT_KHR"); attribs[1] = (1 << 6); /* EGL_OPENGL_ES3_BIT_KHR */ ctx_attribs[1] = 3; break; default: EGL_ELOG("Unknown OpenGL mode set\n"); return false; break; } EGL_ILOG("Calling eglChooseConfig to get number of configs (use16bit=%d)...", (int)use565); EGLConfig *configs; EGLint num_configs; if (!eglChooseConfig(egl_dpy, attribs, NULL, 0, &num_configs) || num_configs == 0) { EGL_ILOG("Error: couldn't get a number of configs. Trying with fallback config (no stencil, not specifying transparent:none)\n"); attribsFallback[1] = attribs[1]; attribs = attribsFallback; if (!eglChooseConfig(egl_dpy, attribs, NULL, 0, &num_configs) || num_configs == 0) { eglTerminate(egl_dpy); return false; } } EGL_ILOG("Got %d configs. Now choosing...", num_configs); configs = new EGLConfig[num_configs]; if (!eglChooseConfig(egl_dpy, attribs, configs, num_configs, &num_configs)) { EGL_ELOG("Error: couldn't get an EGL visual config (num_configs=%d)! Terminating EGL.\n", num_configs); eglTerminate(egl_dpy); return false; } int chosenConfig = -1; // Find our ideal config in the list. If it's there, use it, otherwise pick whatever the device wanted (#0) int wantedAlpha = 8; // Requiring alpha seems to be a problem on older devices. Let's see if this helps... if (attribs[1] == EGL_OPENGL_ES2_BIT) wantedAlpha = 0; for (int i = 0; i < num_configs; i++) { EGL_ILOG("Config %d:", i); LogEGLConfig(egl_dpy, configs[i]); int red, green, blue, alpha, depth, stencil; eglGetConfigAttrib(egl_dpy, configs[i], EGL_RED_SIZE, &red); eglGetConfigAttrib(egl_dpy, configs[i], EGL_GREEN_SIZE, &green); eglGetConfigAttrib(egl_dpy, configs[i], EGL_BLUE_SIZE, &blue); eglGetConfigAttrib(egl_dpy, configs[i], EGL_ALPHA_SIZE, &alpha); eglGetConfigAttrib(egl_dpy, configs[i], EGL_DEPTH_SIZE, &depth); eglGetConfigAttrib(egl_dpy, configs[i], EGL_STENCIL_SIZE, &stencil); if (chosenConfig == -1 && red == 8 && green == 8 && blue == 8 && alpha == wantedAlpha && depth == 24 && stencil == 8) { chosenConfig = i; } } if (chosenConfig == -1) chosenConfig = 0; EGL_ILOG("eglChooseConfig successful: num_configs=%d, choosing config %d", num_configs, chosenConfig); if (s_opengl_mode == MODE_OPENGL) { EGL_ILOG("eglBindAPI(OPENGL)"); eglBindAPI(EGL_OPENGL_API); } else { EGL_ILOG("eglBindAPI(OPENGL_ES)"); eglBindAPI(EGL_OPENGL_ES_API); } EGLNativeWindowType host_window = (EGLNativeWindowType)window_handle; EGLNativeWindowType native_window = InitializePlatform(host_window, configs[chosenConfig]); const char *s = eglQueryString(egl_dpy, EGL_VERSION); EGL_ILOG("EGL_VERSION = %s\n", s); s = eglQueryString(egl_dpy, EGL_VENDOR); EGL_ILOG("EGL_VENDOR = %s\n", s); s = eglQueryString(egl_dpy, EGL_EXTENSIONS); EGL_ILOG("EGL_EXTENSIONS = %s\n", s); s = eglQueryString(egl_dpy, EGL_CLIENT_APIS); EGL_ILOG("EGL_CLIENT_APIS = %s\n", s); egl_ctx = eglCreateContext(egl_dpy, configs[chosenConfig], EGL_NO_CONTEXT, ctx_attribs); if (!egl_ctx) { EGL_ILOG("Error: eglCreateContext failed: %s\n", EGLGetErrorString(eglGetError())); delete[] configs; return false; } EGL_ILOG("Successfully created EGL context.\n"); egl_surf = eglCreateWindowSurface(egl_dpy, configs[chosenConfig], native_window, nullptr); if (!egl_surf) { EGL_ILOG("Error: eglCreateWindowSurface failed: native_window=%p error=%s ctx_attribs[1]==%d\n", native_window, EGLGetErrorString(eglGetError()), ctx_attribs[1]); eglDestroyContext(egl_dpy, egl_ctx); delete[] configs; return false; } EGL_ILOG("Successfully created EGL window surface (window=%p).\n", native_window); delete[] configs; return true; }
// ----------------------------------------------------------------------------- WindowOffscreenEGL::WindowOffscreenEGL(int width, int height) : WindowBase(width, height) , m_display(EGL_NO_DISPLAY) , m_context(EGL_NO_CONTEXT) , m_surface(EGL_NO_SURFACE) , m_stream(EGL_NO_STREAM_KHR) , m_offscreen(true) { eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)eglGetProcAddress("eglQueryDevicesEXT"); eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC)eglGetProcAddress("eglQueryDeviceStringEXT"); eglGetOutputLayersEXT = (PFNEGLGETOUTPUTLAYERSEXTPROC)eglGetProcAddress("eglGetOutputLayersEXT"); eglCreateStreamKHR = (PFNEGLCREATESTREAMKHRPROC)eglGetProcAddress("eglCreateStreamKHR"); eglDestroyStreamKHR = (PFNEGLDESTROYSTREAMKHRPROC)eglGetProcAddress("eglDestroyStreamKHR"); eglCreateStreamProducerSurfaceKHR = (PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)eglGetProcAddress("eglCreateStreamProducerSurfaceKHR"); eglStreamConsumerOutputEXT = (PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)eglGetProcAddress("eglStreamConsumerOutputEXT"); if (!eglGetPlatformDisplayEXT || !eglQueryDevicesEXT || !eglQueryDeviceStringEXT) { std::cout << "WindowEGL: Cannot load EGL extensions: eglGetPlatformDisplayEXT," << " eglQueryDevicesEXT, eglQueryDeviceStringEXT" << std::endl; throw std::exception(); } EGLBoolean status; EGLint deviceCount = 4; EGLint foundDevices = 0; EGLDeviceEXT devices[deviceCount]; // ----------------------- std::cout << "WindowEGL: find EGL devices" << std::endl; { // Get pointers of required EGL functions status = eglQueryDevicesEXT(deviceCount, devices, &foundDevices); if (status != EGL_TRUE) { std::cout << "WindowEGL: Failed to query devices (error: " << std::hex << eglGetError() << ")" << std::dec << std::endl; throw std::exception(); } std::cout << "WindowEGL: found " << foundDevices << " EGL devices" << std::endl; } EGLAttrib layerAttribs[] = { EGL_NONE, EGL_NONE, EGL_NONE, EGL_NONE, }; // ----------------------- if (m_offscreen == false) { // get device name to setup DRM, assume that devices[0] is the one to use const char *drmName = eglQueryDeviceStringEXT(devices[0], EGL_DRM_DEVICE_FILE_EXT); if (!drmName) { std::cout << "WindowEGL: unable to query DRM device name" << std::endl; } else { std::cout << "WindowEGL: use drm device: " << drmName << std::endl; } std::cout << "WindowEGL: init DRM with " << width << "x" << height << " resolution" << std::endl; if (!initDrm(drmName, layerAttribs, m_width, m_height)) { std::cout << "WindowEGL: Failed to init DRM" << std::endl; throw std::exception(); } std::cout << "WindowEGL: DRM initialized, selected resolution is " << m_width << ", " << m_height << std::endl; } // ----------------------- std::cout << "WindowEGL: init EGL with GLES3 context" << std::endl; { EGLenum platform = EGL_PLATFORM_DEVICE_EXT; EGLint dispAttribs[] = {EGL_NONE, EGL_NONE}; // create display on top of DRM display m_display = eglGetPlatformDisplayEXT(platform, (NativeDisplayType)devices[0], dispAttribs); if (m_display == EGL_NO_DISPLAY) { std::cout << "WindowEGL: Failed to create EGL display: " << "eglGetPlatformDisplayEXT failed with: " << std::hex << eglGetError() << std::dec << std::endl; throw std::exception(); } // setup EGL like in windowing system status = eglInitialize(m_display, 0, 0); if (!status) { eglTerminate(m_display); m_display = EGL_NO_DISPLAY; std::cout << "WindowEGL: Could not init EGL eglInitialize failed with: " << std::hex << eglGetError() << std::dec << std::endl; throw std::exception(); } std::cout << "WindowEGL: bind OpenGLES3 API" << std::endl; EGLint cfgAttribs[] = { EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_STREAM_BIT_KHR, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 8, //EGL_STENCIL_SIZE, 8, EGL_NONE, EGL_NONE}; EGLint cfgCount = 0; status = eglChooseConfig(m_display, cfgAttribs, &m_config, 1, &cfgCount); if (!status || cfgCount == 0) { std::cout << "Could not read EGL config count! error: 0x" << std::hex << eglGetError() << std::dec << std::endl; throw std::exception(); } // in offscreen mode we use Pbuffer surface to manage GL context if (m_offscreen == true) { std::cout << "WindowEGL: offscreen mode -> use EGL PBuffer surface " << m_width << "x" << m_height << std::endl; EGLint pbsAttrib[] = { EGL_WIDTH, m_width, EGL_HEIGHT, m_height, //EGL_MIPMAP_TEXTURE, EGL_TRUE, //EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, //EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, EGL_NONE, EGL_NONE}; m_surface = eglCreatePbufferSurface(m_display, m_config, pbsAttrib); // in onscreen mode we pass GL output through EGL stream directly to display device } else { std::cout << "WindowEGL: onscreen mode -> use EGL stream to display" << std::endl; EGLOutputLayerEXT layer; int n; if (!eglGetOutputLayersEXT(m_display, layerAttribs, &layer, 1, &n) || !n) { std::cout << "WindowEGL: Unable to get output layer" << std::endl; throw std::exception(); } // Create a stream and connect to the output EGLint stream_attr[] = { EGL_STREAM_FIFO_LENGTH_KHR, 1, EGL_NONE}; m_stream = eglCreateStreamKHR(m_display, stream_attr); if (m_stream == EGL_NO_STREAM_KHR) { std::cout << "WindowEGL: Unable to create stream" << std::endl; throw std::exception(); } if (!eglStreamConsumerOutputEXT(m_display, m_stream, layer)) { std::cout << "Unable to connect output to stream" << std::endl; return; } EGLint srfAttribs[] = { EGL_WIDTH, m_width, EGL_HEIGHT, m_height, EGL_NONE, EGL_NONE}; // create a surface as EGL stream producer m_surface = eglCreateStreamProducerSurfaceKHR(m_display, m_config, m_stream, srfAttribs); } if (m_surface == EGL_NO_SURFACE) { std::cout << "WindowEGL: Could not create rendering surface: 0x" << std::hex << eglGetError() << std::dec << std::endl; throw std::exception(); } eglBindAPI(EGL_OPENGL_ES_API); } // ----------------------- std::cout << "WindowEGL: create EGL context" << std::endl; { EGLint ctxAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE, EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION_EXT, EGL_NONE, EGL_NONE}; m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, ctxAttribs); if (m_context == EGL_NO_CONTEXT) { std::cout << "WindowEGL: Failed to create EGL context" << std::endl; throw std::exception(); } } // ----------------------- std::cout << "WindowEGL: assign EGL context to current thread" << std::endl; { status = eglMakeCurrent(m_display, m_surface, m_surface, m_context); if (status == EGL_FALSE) { std::cout << "WindowEGL: Could not makeCurrent: " << std::hex << eglGetError() << std::dec << std::endl; throw std::exception(); } } }
void cInterfaceEGL::DetectMode() { EGLint num_configs; bool supportsGL = false, supportsGLES2 = false, supportsGLES3 = false; static const int renderable_types[3] = { EGL_OPENGL_BIT, (1 << 6), /* EGL_OPENGL_ES3_BIT_KHR */ EGL_OPENGL_ES2_BIT, }; static const char *renderable_names[3] = { "OpenGL", "OpenGL ES 3", "OpenGL ES 2" }; for (int i = 0; i < 3; i++) { int renderable_type = renderable_types[i]; const char *renderable_name = renderable_names[i]; // attributes for a visual in RGBA format with at least // 8 bits per color int attribs[] = { EGL_RENDERABLE_TYPE, renderable_type, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_STENCIL_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_TRANSPARENT_TYPE, EGL_NONE, EGL_SAMPLES, 0, EGL_NONE }; // Get how many configs there are if (!eglChooseConfig( egl_dpy, attribs, nullptr, 0, &num_configs)) { EGL_ILOG("DetectMode: couldn't get an EGL visual config with renderable_type=%s", renderable_name); continue; } EGL_ILOG("DetectMode: got an EGL visual config with renderable_type=%s", renderable_name); EGLConfig* config = new EGLConfig[num_configs]; // Get all the configurations if (!eglChooseConfig(egl_dpy, attribs, config, num_configs, &num_configs)) { EGL_ILOG("DetectMode: couldn't choose an EGL visual config\n"); delete[] config; continue; } for (int i = 0; i < num_configs; ++i) { EGLint attribVal; bool ret; ret = eglGetConfigAttrib(egl_dpy, config[i], EGL_RENDERABLE_TYPE, &attribVal); if (ret) { if ((attribVal & EGL_OPENGL_BIT) && s_opengl_mode != GLInterfaceMode::MODE_DETECT_ES) supportsGL = true; if (attribVal & (1 << 6)) /* EGL_OPENGL_ES3_BIT_KHR */ supportsGLES3 = true; // Apparently, this cannot be completely trusted so we implement a fallback to ES 2.0 below. if (attribVal & EGL_OPENGL_ES2_BIT) supportsGLES2 = true; } } delete[] config; } if (supportsGL) s_opengl_mode = GLInterfaceMode::MODE_OPENGL; else if (supportsGLES3) s_opengl_mode = GLInterfaceMode::MODE_OPENGLES3; else if (supportsGLES2) s_opengl_mode = GLInterfaceMode::MODE_OPENGLES2; if (s_opengl_mode == GLInterfaceMode::MODE_DETECT) // Errored before we found a mode s_opengl_mode = GLInterfaceMode::MODE_OPENGL; // Fall back to OpenGL }
EGLConfig QEglConfigChooser::chooseConfig() { QVector<EGLint> configureAttributes = q_createConfigAttributesFromFormat(m_format); configureAttributes.append(EGL_SURFACE_TYPE); configureAttributes.append(surfaceType()); configureAttributes.append(EGL_RENDERABLE_TYPE); bool needsES2Plus = false; switch (m_format.renderableType()) { case QSurfaceFormat::OpenVG: configureAttributes.append(EGL_OPENVG_BIT); break; #ifdef EGL_VERSION_1_4 case QSurfaceFormat::DefaultRenderableType: #ifndef QT_NO_OPENGL if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) configureAttributes.append(EGL_OPENGL_BIT); else #endif // QT_NO_OPENGL needsES2Plus = true; break; case QSurfaceFormat::OpenGL: configureAttributes.append(EGL_OPENGL_BIT); break; #endif case QSurfaceFormat::OpenGLES: if (m_format.majorVersion() == 1) { configureAttributes.append(EGL_OPENGL_ES_BIT); break; } // fall through default: needsES2Plus = true; break; } if (needsES2Plus) { if (m_format.majorVersion() >= 3 && q_hasEglExtension(display(), "EGL_KHR_create_context")) configureAttributes.append(EGL_OPENGL_ES3_BIT_KHR); else configureAttributes.append(EGL_OPENGL_ES2_BIT); } configureAttributes.append(EGL_NONE); EGLConfig cfg = 0; do { // Get the number of matching configurations for this set of properties. EGLint matching = 0; if (!eglChooseConfig(display(), configureAttributes.constData(), 0, 0, &matching) || !matching) continue; // Fetch all of the matching configurations and find the // first that matches the pixel format we wanted. int i = configureAttributes.indexOf(EGL_RED_SIZE); m_confAttrRed = configureAttributes.at(i+1); i = configureAttributes.indexOf(EGL_GREEN_SIZE); m_confAttrGreen = configureAttributes.at(i+1); i = configureAttributes.indexOf(EGL_BLUE_SIZE); m_confAttrBlue = configureAttributes.at(i+1); i = configureAttributes.indexOf(EGL_ALPHA_SIZE); m_confAttrAlpha = i == -1 ? 0 : configureAttributes.at(i+1); QVector<EGLConfig> configs(matching); eglChooseConfig(display(), configureAttributes.constData(), configs.data(), configs.size(), &matching); if (!cfg && matching > 0) cfg = configs.first(); // Filter the list. Due to the EGL sorting rules configs with higher depth are // placed first when the minimum color channel sizes have been specified (i.e. the // QSurfaceFormat contains color sizes > 0). To prevent returning a 888 config // when the QSurfaceFormat explicitly asked for 565, go through the returned // configs and look for one that exactly matches the requested sizes. When no // sizes have been given, take the first, which will be a config with the smaller // (e.g. 16-bit) depth. for (int i = 0; i < configs.size(); ++i) { if (filterConfig(configs[i])) return configs.at(i); } } while (q_reduceConfigAttributes(&configureAttributes)); if (!cfg) qWarning("Cant find EGLConfig, returning null config"); return cfg; }
SDL_GLContext PSP_GL_CreateContext(_THIS, SDL_Window * window) { SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; EGLint attribs[32]; EGLDisplay display; EGLContext context; EGLSurface surface; EGLConfig config; EGLint num_configs; int i; /* EGL init taken from glutCreateWindow() in PSPGL's glut.c. */ EGLCHK(display = eglGetDisplay(0)); EGLCHK(eglInitialize(display, NULL, NULL)); wdata->uses_gles = SDL_TRUE; window->flags |= SDL_WINDOW_FULLSCREEN; /* Setup the config based on SDL's current values. */ i = 0; attribs[i++] = EGL_RED_SIZE; attribs[i++] = _this->gl_config.red_size; attribs[i++] = EGL_GREEN_SIZE; attribs[i++] = _this->gl_config.green_size; attribs[i++] = EGL_BLUE_SIZE; attribs[i++] = _this->gl_config.blue_size; attribs[i++] = EGL_DEPTH_SIZE; attribs[i++] = _this->gl_config.depth_size; if (_this->gl_config.alpha_size) { attribs[i++] = EGL_ALPHA_SIZE; attribs[i++] = _this->gl_config.alpha_size; } if (_this->gl_config.stencil_size) { attribs[i++] = EGL_STENCIL_SIZE; attribs[i++] = _this->gl_config.stencil_size; } attribs[i++] = EGL_NONE; EGLCHK(eglChooseConfig(display, attribs, &config, 1, &num_configs)); if (num_configs == 0) { SDL_SetError("No valid EGL configs for requested mode"); return 0; } EGLCHK(eglGetConfigAttrib(display, config, EGL_WIDTH, &width)); EGLCHK(eglGetConfigAttrib(display, config, EGL_HEIGHT, &height)); EGLCHK(context = eglCreateContext(display, config, NULL, NULL)); EGLCHK(surface = eglCreateWindowSurface(display, config, 0, NULL)); EGLCHK(eglMakeCurrent(display, surface, surface, context)); _this->gl_data->display = display; _this->gl_data->context = context; _this->gl_data->surface = surface; return context; }
static void init_egl(struct display *display, struct window *window) { static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; const char *extensions; EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; EGLint major, minor, n, count, i, size; EGLConfig *configs; EGLBoolean ret; if (window->opaque || window->buffer_size == 16) config_attribs[9] = 0; display->egl.dpy = eglGetDisplay(display->display); assert(display->egl.dpy); ret = eglInitialize(display->egl.dpy, &major, &minor); assert(ret == EGL_TRUE); ret = eglBindAPI(EGL_OPENGL_ES_API); assert(ret == EGL_TRUE); if (!eglGetConfigs(display->egl.dpy, NULL, 0, &count) || count < 1) assert(0); configs = calloc(count, sizeof *configs); assert(configs); ret = eglChooseConfig(display->egl.dpy, config_attribs, configs, count, &n); assert(ret && n >= 1); for (i = 0; i < n; i++) { eglGetConfigAttrib(display->egl.dpy, configs[i], EGL_BUFFER_SIZE, &size); if (window->buffer_size == size) { display->egl.conf = configs[i]; break; } } free(configs); if (display->egl.conf == NULL) { fprintf(stderr, "did not find config with buffer size %d\n", window->buffer_size); exit(EXIT_FAILURE); } display->egl.ctx = eglCreateContext(display->egl.dpy, display->egl.conf, EGL_NO_CONTEXT, context_attribs); assert(display->egl.ctx); display->swap_buffers_with_damage = NULL; extensions = eglQueryString(display->egl.dpy, EGL_EXTENSIONS); if (extensions && strstr(extensions, "EGL_EXT_swap_buffers_with_damage") && strstr(extensions, "EGL_EXT_buffer_age")) display->swap_buffers_with_damage = (PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) eglGetProcAddress("eglSwapBuffersWithDamageEXT"); if (display->swap_buffers_with_damage) printf("has EGL_EXT_buffer_age and EGL_EXT_swap_buffers_with_damage\n"); }
static MechEGLConfigPrivate * _create_egl_config (gint renderable_type) { EGLint major, minor, n_configs; MechBackendWayland *backend; MechEGLConfigPrivate *priv; const gchar *extensions; MechEGLConfig *config; GError *error; EGLenum api; const EGLint argb_config_attributes[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_RENDERABLE_TYPE, renderable_type, EGL_NONE }; priv = g_new0 (MechEGLConfigPrivate, 1); config = (MechEGLConfig *) priv; if (renderable_type != EGL_OPENGL_BIT && renderable_type != EGL_OPENGL_ES_BIT && renderable_type != EGL_OPENGL_ES2_BIT) { error = g_error_new (mech_surface_egl_error_quark (), 0, "Not a valid renderable type"); goto init_failed; } backend = _mech_backend_wayland_get (); config->egl_display = eglGetDisplay (backend->wl_display); if (eglInitialize (config->egl_display, &major, &minor) == EGL_FALSE) { error = g_error_new (mech_surface_egl_error_quark (), 0, "Could not initialize EGL"); goto init_failed; } api = (renderable_type == EGL_OPENGL_BIT) ? EGL_OPENGL_API : EGL_OPENGL_ES_API; if (eglBindAPI (api) == EGL_FALSE) { error = g_error_new (mech_surface_egl_error_quark (), 0, "Could not bind a rendering API"); goto init_failed; } if (eglChooseConfig (config->egl_display, argb_config_attributes, &config->egl_argb_config, 1, &n_configs) == EGL_FALSE) { error = g_error_new (mech_surface_egl_error_quark (), 0, "Could not find a matching configuration"); goto init_failed; } config->egl_argb_context = eglCreateContext (config->egl_display, config->egl_argb_config, EGL_NO_CONTEXT, NULL); if (config->egl_argb_context == EGL_NO_CONTEXT) { error = g_error_new (mech_surface_egl_error_quark (), 0, "Could not create an EGL context"); goto init_failed; } if (eglMakeCurrent (config->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, config->egl_argb_context) == EGL_FALSE) { error = g_error_new (mech_surface_egl_error_quark (), 0, "Could not make EGL context current"); goto init_failed; } config->argb_device = cairo_egl_device_create (config->egl_display, config->egl_argb_context); if (cairo_device_status (config->argb_device) != CAIRO_STATUS_SUCCESS) { error = g_error_new (mech_surface_egl_error_quark (), 0, "Could not create a cairo EGL device"); goto init_failed; } extensions = eglQueryString (config->egl_display, EGL_EXTENSIONS); if (strstr (extensions, "EGL_EXT_buffer_age")) config->has_buffer_age_ext = TRUE; if (strstr (extensions, "EGL_EXT_swap_buffers_with_damage")) config->has_swap_buffers_with_damage_ext = TRUE; return priv; init_failed: if (config->egl_argb_context != EGL_NO_CONTEXT) { eglDestroyContext (config->egl_display, config->egl_argb_context); config->egl_argb_context = EGL_NO_CONTEXT; } if (config->argb_device) { cairo_device_destroy (config->argb_device); config->argb_device = NULL; } priv->error = error; return priv; }
int initOpenGL(int device_id) { if (is_initialized) return 1; // desired config const EGLint configAttribs[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE }; EGLDeviceEXT eglDevs[MAX_DEVICES]; EGLint numDevices; PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC) eglGetProcAddress("eglQueryDevicesEXT"); eglQueryDevicesEXT(MAX_DEVICES, eglDevs, &numDevices); printf("Found %d GPUs for rendering. Using device %d.\n", numDevices, device_id); if (device_id >= numDevices) { printf("Device id outside of range of available devices.\n"); return -1; } PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) eglGetProcAddress("eglGetPlatformDisplayEXT"); if (eglGetPlatformDisplayEXT == NULL) { printf("Failed to get eglGetPlatformDisplayEXT\n"); return -2; } EGLDisplay eglDpy = eglGetPlatformDisplayEXT( EGL_PLATFORM_DEVICE_EXT, eglDevs[device_id], 0); // get default display // EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (eglDpy == EGL_NO_DISPLAY) { printf("Could not get EGL display\n"); return -3; } // initialize EGLint major, minor; if (eglInitialize(eglDpy, &major, &minor) != EGL_TRUE) { printf("Could not initialize EGL\n"); return -4; } // choose config EGLint numConfigs; EGLConfig eglCfg; if (eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs)!=EGL_TRUE ) { printf("Could not choose EGL config\n"); return -5; } // bind OpenGL API if( eglBindAPI(EGL_OPENGL_API)!=EGL_TRUE ) { printf("Could not bind EGL OpenGL API\n"); return -6; } // create context EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, NULL); if( eglCtx==EGL_NO_CONTEXT ) { printf("Could not create EGL context\n"); return -7; } // make context current, no surface (let OpenGL handle FBO) if( eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx)!=EGL_TRUE ) { eglDestroyContext(eglDpy, eglCtx); printf("Could not make EGL context current\n"); return -8; } is_initialized = 1; return 1; }
bool TizenGraphicsManager::loadEgl() { logEntered(); EGLint numConfigs = 1; EGLint eglConfigList[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_DEPTH_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE }; EGLint eglContextList[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; eglBindAPI(EGL_OPENGL_ES_API); _eglDisplay = eglGetDisplay((EGLNativeDisplayType) EGL_DEFAULT_DISPLAY); if (EGL_NO_DISPLAY == _eglDisplay) { systemError("eglGetDisplay() failed"); return false; } if (EGL_FALSE == eglInitialize(_eglDisplay, NULL, NULL) || EGL_SUCCESS != eglGetError()) { systemError("eglInitialize() failed"); return false; } if (EGL_FALSE == eglChooseConfig(_eglDisplay, eglConfigList, &_eglConfig, 1, &numConfigs) || EGL_SUCCESS != eglGetError()) { systemError("eglChooseConfig() failed"); return false; } if (!numConfigs) { systemError("eglChooseConfig() failed. Matching config does not exist \n"); return false; } _eglSurface = eglCreateWindowSurface(_eglDisplay, _eglConfig, (EGLNativeWindowType)_appForm, NULL); if (EGL_NO_SURFACE == _eglSurface || EGL_SUCCESS != eglGetError()) { systemError("eglCreateWindowSurface() failed. EGL_NO_SURFACE"); return false; } _eglContext = eglCreateContext(_eglDisplay, _eglConfig, EGL_NO_CONTEXT, eglContextList); if (EGL_NO_CONTEXT == _eglContext || EGL_SUCCESS != eglGetError()) { systemError("eglCreateContext() failed"); return false; } if (false == eglMakeCurrent(_eglDisplay, _eglSurface, _eglSurface, _eglContext) || EGL_SUCCESS != eglGetError()) { systemError("eglMakeCurrent() failed"); return false; } logLeaving(); return true; }