void test_triangle_smoothed(GLenum mode) { GLint width, height; GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f }; GLfloat vColors[] = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f}; EGLSurface surface; RD_START("triangle-smoothed", ""); display = get_display(); /* get an appropriate EGL frame buffer configuration */ ECHK(eglChooseConfig(display, config_attribute_list, &config, 1, &num_config)); DEBUG_MSG("num_config: %d", num_config); /* create an EGL rendering context */ ECHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribute_list)); surface = make_window(display, config, 400, 240); ECHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); ECHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); DEBUG_MSG("Buffer: %dx%d", width, height); /* connect the context to the surface */ ECHK(eglMakeCurrent(display, surface, surface, context)); program = get_program(vertex_shader_source, fragment_shader_source); GCHK(glBindAttribLocation(program, 0, "aPosition")); GCHK(glBindAttribLocation(program, 1, "aColor")); link_program(program); GCHK(glViewport(0, 0, width, height)); GCHK(glFrontFace(mode)); /* clear the color buffer */ GCHK(glClearColor(0.0, 0.0, 0.0, 1.0)); GCHK(glClear(GL_COLOR_BUFFER_BIT)); GCHK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices)); GCHK(glEnableVertexAttribArray(0)); GCHK(glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, vColors)); GCHK(glEnableVertexAttribArray(1)); GCHK(glDrawArrays(GL_TRIANGLES, 0, 3)); ECHK(eglSwapBuffers(display, surface)); GCHK(glFlush()); ECHK(eglDestroySurface(display, surface)); ECHK(eglTerminate(display)); RD_END(); }
/* * Create an RGB, double-buffered X window. * Return the window and context handles. */ static void make_x_window(Display *x_dpy, EGLDisplay egl_dpy, const char *name, int x, int y, int width, int height, Window *winRet, EGLContext *ctxRet, EGLSurface *surfRet) { static const EGLint attribs[] = { EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_DEPTH_SIZE, 1, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; static const EGLint ctx_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; int scrnum; XSetWindowAttributes attr; unsigned long mask; Window root; Window win; XVisualInfo *visInfo, visTemplate; int num_visuals; EGLContext ctx; EGLConfig config; EGLint num_configs; EGLint vid; scrnum = DefaultScreen( x_dpy ); root = RootWindow( x_dpy, scrnum ); if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs)) { printf("Error: couldn't get an EGL visual config\n"); exit(1); } assert(config); assert(num_configs > 0); if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) { printf("Error: eglGetConfigAttrib() failed\n"); exit(1); } /* The X window visual must match the EGL config */ visTemplate.visualid = vid; visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); if (!visInfo) { printf("Error: couldn't get X visual\n"); exit(1); } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; win = XCreateWindow( x_dpy, root, 0, 0, width, height, 0, visInfo->depth, InputOutput, visInfo->visual, mask, &attr ); /* set hints and properties */ { XSizeHints sizehints; sizehints.x = x; sizehints.y = y; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; XSetNormalHints(x_dpy, win, &sizehints); XSetStandardProperties(x_dpy, win, name, name, None, (char **)NULL, 0, &sizehints); } #if USE_FULL_GL /* XXX fix this when eglBindAPI() works */ eglBindAPI(EGL_OPENGL_API); #else eglBindAPI(EGL_OPENGL_ES_API); #endif ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs ); if (!ctx) { printf("Error: eglCreateContext failed\n"); exit(1); } /* test eglQueryContext() */ { EGLint val; eglQueryContext(egl_dpy, ctx, EGL_CONTEXT_CLIENT_VERSION, &val); assert(val == 2); } *surfRet = eglCreateWindowSurface(egl_dpy, config, win, NULL); if (!*surfRet) { printf("Error: eglCreateWindowSurface failed\n"); exit(1); } /* sanity checks */ { EGLint val; eglQuerySurface(egl_dpy, *surfRet, EGL_WIDTH, &val); assert(val == width); eglQuerySurface(egl_dpy, *surfRet, EGL_HEIGHT, &val); assert(val == height); assert(eglGetConfigAttrib(egl_dpy, config, EGL_SURFACE_TYPE, &val)); assert(val & EGL_WINDOW_BIT); } XFree(visInfo); *winRet = win; *ctxRet = ctx; }
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; }
/// // 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; EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE }; // Get Display display = eglGetDisplay((EGLNativeDisplayType)x_display); if ( display == EGL_NO_DISPLAY ) { return EGL_FALSE; } // 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 EGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLContext *share) { m_format = EglUtils::glFormatFromConfig(m_eglDisplay, m_eglConfig); // m_format now has the renderableType() resolved (it cannot be Default anymore) // but does not yet contain version, profile, options. m_shareContext = share ? static_cast<EGLPlatformContext *>(share)->m_eglContext : 0; QVector<EGLint> contextAttrs; contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); contextAttrs.append(format.majorVersion()); const bool hasKHRCreateContext = EglUtils::hasEglExtension(m_eglDisplay, "EGL_KHR_create_context"); if (hasKHRCreateContext) { contextAttrs.append(EGL_CONTEXT_MINOR_VERSION_KHR); contextAttrs.append(format.minorVersion()); int flags = 0; // The debug bit is supported both for OpenGL and OpenGL ES. if (format.testOption(QSurfaceFormat::DebugContext)) flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; // The fwdcompat bit is only for OpenGL 3.0+. if (m_format.renderableType() == QSurfaceFormat::OpenGL && format.majorVersion() >= 3 && !format.testOption(QSurfaceFormat::DeprecatedFunctions)) flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; if (flags) { contextAttrs.append(EGL_CONTEXT_FLAGS_KHR); contextAttrs.append(flags); } // Profiles are OpenGL only and mandatory in 3.2+. The value is silently ignored for < 3.2. if (m_format.renderableType() == QSurfaceFormat::OpenGL) { contextAttrs.append(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR); contextAttrs.append(format.profile() == QSurfaceFormat::CoreProfile ? EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR : EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR); } } contextAttrs.append(EGL_NONE); m_contextAttrs = contextAttrs; switch (m_format.renderableType()) { case QSurfaceFormat::OpenVG: m_api = EGL_OPENVG_API; break; #ifdef EGL_VERSION_1_4 case QSurfaceFormat::OpenGL: m_api = EGL_OPENGL_API; break; #endif // EGL_VERSION_1_4 default: m_api = EGL_OPENGL_ES_API; break; } eglBindAPI(m_api); m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, m_shareContext, contextAttrs.constData()); if (m_eglContext == EGL_NO_CONTEXT && m_shareContext != EGL_NO_CONTEXT) { m_shareContext = 0; m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, 0, contextAttrs.constData()); } if (m_eglContext == EGL_NO_CONTEXT) { qCWarning(lcEglConvenience, "Failed to create context: %x", eglGetError()); return; } static const bool printConfig = qEnvironmentVariableIntValue("GREENISLAND_QPA_DEBUG"); if (printConfig) { qCInfo(lcEglConvenience) << "Created context for format" << format << "with config:"; EglUtils::printEglConfig(m_eglDisplay, m_eglConfig); } // Cannot just call updateFormatFromGL() since it relies on virtuals. Defer it to initialize(). }
void EGLPlatformContext::updateFormatFromGL() { #ifndef QT_NO_OPENGL // Have to save & restore to prevent QOpenGLContext::currentContext() from becoming // inconsistent after QOpenGLContext::create(). EGLDisplay prevDisplay = eglGetCurrentDisplay(); if (prevDisplay == EGL_NO_DISPLAY) // when no context is current prevDisplay = m_eglDisplay; EGLContext prevContext = eglGetCurrentContext(); EGLSurface prevSurfaceDraw = eglGetCurrentSurface(EGL_DRAW); EGLSurface prevSurfaceRead = eglGetCurrentSurface(EGL_READ); // Rely on the surfaceless extension, if available. This is beneficial since we can // avoid creating an extra pbuffer surface which is apparently troublesome with some // drivers (Mesa) when certain attributes are present (multisampling). EGLSurface tempSurface = EGL_NO_SURFACE; EGLContext tempContext = EGL_NO_CONTEXT; if (m_flags.testFlag(NoSurfaceless) || !EglUtils::hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context")) tempSurface = createTemporaryOffscreenSurface(); EGLBoolean ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext); if (!ok) { EGLConfig config = EglUtils::configFromGLFormat(m_eglDisplay, m_format, false, EGL_PBUFFER_BIT); tempContext = eglCreateContext(m_eglDisplay, config, 0, m_contextAttrs.constData()); if (tempContext != EGL_NO_CONTEXT) ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, tempContext); } if (ok) { if (m_format.renderableType() == QSurfaceFormat::OpenGL || m_format.renderableType() == QSurfaceFormat::OpenGLES) { const GLubyte *s = glGetString(GL_VERSION); if (s) { QByteArray version = QByteArray(reinterpret_cast<const char *>(s)); int major, minor; if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) { #ifdef Q_OS_ANDROID // Some Android 4.2.2 devices report OpenGL ES 3.0 without the functions being available. static int apiLevel = QtAndroidPrivate::androidSdkVersion(); if (apiLevel <= 17 && major >= 3) { major = 2; minor = 0; } #endif m_format.setMajorVersion(major); m_format.setMinorVersion(minor); } } m_format.setProfile(QSurfaceFormat::NoProfile); m_format.setOptions(QSurfaceFormat::FormatOptions()); if (m_format.renderableType() == QSurfaceFormat::OpenGL) { // Check profile and options. if (m_format.majorVersion() < 3) { m_format.setOption(QSurfaceFormat::DeprecatedFunctions); } else { GLint value = 0; glGetIntegerv(GL_CONTEXT_FLAGS, &value); if (!(value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)) m_format.setOption(QSurfaceFormat::DeprecatedFunctions); if (value & GL_CONTEXT_FLAG_DEBUG_BIT) m_format.setOption(QSurfaceFormat::DebugContext); if (m_format.version() >= qMakePair(3, 2)) { value = 0; glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value); if (value & GL_CONTEXT_CORE_PROFILE_BIT) m_format.setProfile(QSurfaceFormat::CoreProfile); else if (value & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) m_format.setProfile(QSurfaceFormat::CompatibilityProfile); } } } } runGLchecks(); eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext); } else { qCWarning(lcEglConvenience, "Failed to make temporary surface current, format not updated (%x)", eglGetError()); } if (tempSurface != EGL_NO_SURFACE) destroyTemporaryOffscreenSurface(tempSurface); if (tempContext != EGL_NO_CONTEXT) eglDestroyContext(m_eglDisplay, tempContext); #endif // QT_NO_OPENGL }
static bool egl_create_context(struct vo_wayland_state *wl, struct egl_context *egl_ctx, MPGLContext *ctx, bool enable_alpha) { EGLint major, minor, n; GL *gl = ctx->gl; const char *eglstr = ""; if (!(egl_ctx->egl.dpy = eglGetDisplay(wl->display.display))) return false; 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(egl_ctx->egl.dpy, &major, &minor) != EGL_TRUE) return false; MP_VERBOSE(wl->vo, "EGL version %d.%d\n", major, minor); EGLint context_attribs[] = { EGL_CONTEXT_MAJOR_VERSION_KHR, MPGL_VER_GET_MAJOR(ctx->requested_gl_version), /* EGL_CONTEXT_MINOR_VERSION_KHR, */ /* MPGL_VER_GET_MINOR(ctx->requested_gl_version), */ /* EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR, 0, */ /* Segfaults on anything else than the major version */ EGL_NONE }; if (eglBindAPI(EGL_OPENGL_API) != EGL_TRUE) return false; eglChooseConfig(egl_ctx->egl.dpy, config_attribs, &egl_ctx->egl.conf, 1, &n); egl_ctx->egl.ctx = eglCreateContext(egl_ctx->egl.dpy, egl_ctx->egl.conf, EGL_NO_CONTEXT, context_attribs); if (!egl_ctx->egl.ctx) { /* fallback to any GL version */ context_attribs[0] = EGL_NONE; egl_ctx->egl.ctx = eglCreateContext(egl_ctx->egl.dpy, egl_ctx->egl.conf, EGL_NO_CONTEXT, context_attribs); if (!egl_ctx->egl.ctx) return false; } eglMakeCurrent(egl_ctx->egl.dpy, NULL, NULL, egl_ctx->egl.ctx); eglstr = eglQueryString(egl_ctx->egl.dpy, EGL_EXTENSIONS); mpgl_load_functions(gl, (void*(*)(const GLubyte*))eglGetProcAddress, eglstr); if (!gl->BindProgram) mpgl_load_functions(gl, NULL, eglstr); return true; }
static gboolean _initialize_opengl_backend (gboolean bForceOpenGL) { gboolean bStencilBufferAvailable = TRUE, bAlphaAvailable = TRUE; // open a connection (= Display) to the graphic server EGLNativeDisplayType display_id = EGL_DEFAULT_DISPLAY; // XDisplay*, wl_display*, etc; Note: we could pass our X Display instead of making a new connection... EGLDisplay *dpy = s_eglDisplay = eglGetDisplay (display_id); int major, minor; if (! eglInitialize (dpy, &major, &minor)) { cd_warning ("Can't initialise EGL display, OpenGL will not be available"); return FALSE; } g_print ("EGL version: %d;%d\n", major, minor); // find a Frame Buffer Configuration (= Visual) that supports the features we need EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, // EGL_OPENGL_ES2_BIT EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_DEPTH_SIZE, 1, EGL_ALPHA_SIZE, 8, EGL_STENCIL_SIZE , 1, EGL_SAMPLES, 4, EGL_SAMPLE_BUFFERS, 1, EGL_NONE }; const EGLint ctx_attribs[] = { EGL_NONE }; EGLConfig config; EGLint numConfigs=0; eglChooseConfig (dpy, config_attribs, &config, 1, &numConfigs); if (numConfigs == 0) { cd_warning ("couldn't find an appropriate visual, trying to get one without Stencil buffer\n(it may cause some little deterioration in the rendering) ..."); config_attribs[14] = EGL_NONE; bStencilBufferAvailable = FALSE; eglChooseConfig (dpy, config_attribs, &config, 1, &numConfigs); if (numConfigs == 0 && bForceOpenGL) { // if still no luck, and user insisted on using OpenGL, give up on transparency. if (bForceOpenGL) { cd_warning ("we could not get an ARGB-visual, trying to get an RGB one (fake transparency will be used in return) ..."); config_attribs[12] = None; bAlphaAvailable = FALSE; eglChooseConfig (dpy, config_attribs, &config, 1, &numConfigs); } } if (numConfigs == 0) { cd_warning ("No EGL config matching an RGBA buffer, OpenGL will not be available"); return FALSE; } } g_openglConfig.bStencilBufferAvailable = bStencilBufferAvailable; g_openglConfig.bAlphaAvailable = bAlphaAvailable; s_eglConfig = config; // create a rendering context (All other context will share ressources with it, and it will be the default context in case no other context exist) eglBindAPI (EGL_OPENGL_API); // specify the type of client API context before we create one. s_eglContext = eglCreateContext (dpy, config, EGL_NO_CONTEXT, ctx_attribs); if (s_eglContext == EGL_NO_CONTEXT) { cd_warning ("Couldn't create an EGL context, OpenGL will not be available"); return FALSE; } // check some texture abilities g_openglConfig.bTextureFromPixmapAvailable = _check_client_egl_extension ("EGL_EXT_texture_from_pixmap"); cd_debug ("bTextureFromPixmapAvailable: %d", g_openglConfig.bTextureFromPixmapAvailable); if (g_openglConfig.bTextureFromPixmapAvailable) { g_openglConfig.bindTexImage = (gpointer)eglGetProcAddress ("eglBindTexImageEXT"); g_openglConfig.releaseTexImage = (gpointer)eglGetProcAddress ("eglReleaseTexImageEXT"); g_openglConfig.bTextureFromPixmapAvailable = (g_openglConfig.bindTexImage && g_openglConfig.releaseTexImage); } return TRUE; }
//display int init_display() { int32_t success = 0; EGLBoolean result; EGLint num_config; 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; EGLConfig config; //creates problem is func eglCreateContext static const EGLint attribute_list[] = { //EGL_COLOR_BUFFER_TYPE, EGL_LUMINANCE_BUFFER, //EGL_RGB_BUFFER EGL_RED_SIZE, 8, // default is 0 EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, //EGL_LUMINANCE_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; static const EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; memset( &m_display, 0, sizeof(display) ); bcm_host_init(); // must be called be4 any gpu function is called m_display.display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (m_display.display==EGL_NO_DISPLAY) { printf("init_opengl : error in eglGetDisplay\n"); exit(-1); } result = eglInitialize(m_display.display, NULL, NULL); if (EGL_FALSE == result) { printf("init_opengl : error in initializing EGL Display\n"); exit(-1); } result = eglChooseConfig(m_display.display, attribute_list, &config, 17*sizeof(attribute_list[0]), &num_config); if (EGL_FALSE == result) { printf("init_opengl : error in getting egl frame buffer configuration\n"); exit(-1); } result = eglBindAPI(EGL_OPENGL_ES_API); if (EGL_FALSE == result) { printf("init_opengl : error in binding api\n"); exit(-1); } m_display.context = eglCreateContext(m_display.display, config, EGL_NO_CONTEXT, context_attributes); if (m_display.context==EGL_NO_CONTEXT) { printf("init_opengl : error in creating context . \n"); exit(-1); } // create an EGL window surface (video core api)(bug 1920*1080 always)(only for rpi) success = graphics_get_display_size(0 /*display number*/, &m_display.scr_width, &m_display.scr_height); if ( success < 0 ) { printf("init_opengl : error in creating EGL window surface\n"); exit(-1); } if ( glGetError() != 0 ) { printf("init_opengl : error - exit point 1.\n"); exit(-1); } dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = m_display.scr_width; dst_rect.height = m_display.scr_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = m_display.scr_width << 16; src_rect.height = m_display.scr_height << 16; dispman_display = vc_dispmanx_display_open( 0 /*display number*/); 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*/, (DISPMANX_TRANSFORM_T)0/*transform*/); m_display.nativewindow.element = dispman_element; m_display.nativewindow.width = m_display.scr_width; m_display.nativewindow.height = m_display.scr_height; vc_dispmanx_update_submit_sync( dispman_update ); if ( glGetError() != 0 ) { printf("init_opengl : error - exit point 2.\n"); exit(-1); } m_display.surface = eglCreateWindowSurface( m_display.display, config, &m_display.nativewindow, NULL ); if(m_display.surface == EGL_NO_SURFACE) { printf("init_opengl : error could not create window surface\n"); exit(-1); } // connect the context to the surface result = eglMakeCurrent(m_display.display, m_display.surface, m_display.surface, m_display.context); if ( EGL_FALSE == result ) { printf("init_opengl : error - could not connect context to surface\n"); exit(-1); } if ( glGetError() != 0 ) { printf("init_opengl : error - exit point 3.\n"); exit(-1); } glClear( GL_COLOR_BUFFER_BIT ); glViewport ( 0, 0, m_display.scr_width, m_display.scr_height ); if ( glGetError() != 0 ) { printf("init_opengl : error - exit point 4.\n"); exit(-1); } m_display.scr_aspect_ratio = (float) ( ((float)m_display.scr_width) / ((float)m_display.scr_height) ); return(0); }
/// // esCreateWindow() // // width - width of window to create // height - height of window to create // flags - bitwise or of window creation flags // ES_WINDOW_ALPHA - specifies that the framebuffer should have alpha // ES_WINDOW_DEPTH - specifies that a depth buffer should be created // ES_WINDOW_STENCIL - specifies that a stencil buffer should be created // ES_WINDOW_MULTISAMPLE - specifies that a multi-sample buffer should be created // GLboolean ESUTIL_API esCreateWindow(ESContext *esContext, GLint width, GLint height, GLuint flags) { EGLint attribList[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; if (esContext == NULL) { return GL_FALSE; } esContext->width = width; esContext->height = height; int32_t success = 0; 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; int display_width; int display_height; // create an EGL window surface, passing context width/height success = graphics_get_display_size(0 /* LCD */, &display_width, &display_height); if (success < 0) { return EGL_FALSE; } dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = display_width; dst_rect.height = display_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = display_width << 16; src_rect.height = display_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 = display_width; nativewindow.height = display_height; vc_dispmanx_update_submit_sync(dispman_update); esContext->hWnd = &nativewindow; esContext->width = display_width; esContext->height = display_height; EGLint numConfigs; EGLint majorVersion; EGLint minorVersion; EGLDisplay display; EGLContext context; EGLSurface surface; EGLConfig config; EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (display == EGL_NO_DISPLAY) { return GL_FALSE; } if (!eglInitialize(display, &majorVersion, &minorVersion)) { return GL_FALSE; } // Get configs if (!eglGetConfigs(display, NULL, 0, &numConfigs)) { return GL_FALSE; } // Choose config if (!eglChooseConfig(display, attribList, &config, 1, &numConfigs)) { return GL_FALSE; } // Create a surface surface = eglCreateWindowSurface(display, config, esContext->hWnd, NULL); if (surface == EGL_NO_SURFACE) { return GL_FALSE; } // Create a GL context context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs); if (context == EGL_NO_CONTEXT) { return GL_FALSE; } // Make the context current if (!eglMakeCurrent(display, surface, surface, context)) { return GL_FALSE; } esContext->eglDisplay = display; esContext->eglSurface = surface; esContext->eglContext = context; return GL_TRUE; }
void RenderWorld::init() { const EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_NONE }; EGLint format; EGLint numConfigs; EGLConfig config; mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(mDisplay, 0, 0); eglChooseConfig(mDisplay, attribs, &config, 1, &numConfigs); eglGetConfigAttrib(mDisplay, config, EGL_NATIVE_VISUAL_ID, &format); ANativeWindow_setBuffersGeometry(mAndroidApp->window, 0, 0, format); mSurface = eglCreateWindowSurface(mDisplay, config, mAndroidApp->window, NULL); EGLint c_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; mContext = eglCreateContext(mDisplay, config, 0, c_attribs); if (eglMakeCurrent(mDisplay, mSurface, mSurface, mContext) == EGL_FALSE) throw Exception("eglMakeCurrent failed"); eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth); eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight); mView = Matrix::createLookAt(Vector3::ONE*25, Vector3::ZERO, Vector3::UNIT_Y); mProj = Matrix::createPerspectiveFOV(Math::PI/3.0f, (float)mWidth/(float)mHeight, 1.0f, 1000.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); shared_ptr<ResourceLoader> vloader(new VertexShaderLoader); shared_ptr<ResourceLoader> ploader(new PixelShaderLoader); shared_ptr<ResourceLoader> mloader(new MeshLoader); shared_ptr<ResourceLoader> tloader(new TextureLoader); shared_ptr<ResourceLoader> mtloader(new MaterialLoader); shared_ptr<ResourceLoader> skloader(new SkinLoader); ResourceManager& rman = Engine::getPtr()->getResourceManager(); rman.addLoader(vloader); rman.addLoader(ploader); rman.addLoader(mloader); rman.addLoader(tloader); rman.addLoader(mtloader); rman.addLoader(skloader); VertexShader* vshader = rman.get<VertexShader>("test.vs"); PixelShader* pshader = rman.get<PixelShader>("test.fs"); mProgram = new Program; mProgram->attach(*vshader); mProgram->attach(*pshader); mProgram->link(); }
bool RendererGlAndroid::initialize( ANativeWindow *nativeWindow, RendererRef sharedRenderer ) { std::vector<EGLint> configAttribs; // OpenGL ES 3 also uses EGL_OPENGL_ES2_BIT configAttribs.push_back( EGL_RENDERABLE_TYPE ); configAttribs.push_back( EGL_OPENGL_ES2_BIT ); configAttribs.push_back( EGL_SURFACE_TYPE ); configAttribs.push_back( EGL_WINDOW_BIT ); configAttribs.push_back( EGL_RED_SIZE ); configAttribs.push_back( 8 ); configAttribs.push_back( EGL_GREEN_SIZE ); configAttribs.push_back( 8 ); configAttribs.push_back( EGL_BLUE_SIZE ); configAttribs.push_back( 8 ); configAttribs.push_back( EGL_ALPHA_SIZE ); configAttribs.push_back( EGL_DONT_CARE ); configAttribs.push_back( EGL_DEPTH_SIZE ); configAttribs.push_back( mRenderer->getOptions().getDepthBufferDepth() ); configAttribs.push_back( EGL_STENCIL_SIZE ); configAttribs.push_back( mRenderer->getOptions().getStencil() ? 8 : EGL_DONT_CARE ); configAttribs.push_back( EGL_SAMPLE_BUFFERS ); configAttribs.push_back( 1 ); configAttribs.push_back( EGL_NONE ); EGLint surfaceAttribList[] = { EGL_NONE, EGL_NONE }; mDisplay = eglGetDisplay( EGL_DEFAULT_DISPLAY ); if( mDisplay == EGL_NO_DISPLAY) { return false; } EGLint majorVersion, minorVersion; if( ! eglInitialize( mDisplay, &majorVersion, &minorVersion ) ) { return false; } eglBindAPI( EGL_OPENGL_ES_API ); if( eglGetError() != EGL_SUCCESS ) { return false; } EGLint configCount; if( ! eglChooseConfig( mDisplay, configAttribs.data(), &mConfig, 1, &configCount ) || (configCount != 1) ) { return false; } // // 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. // EGLint format; eglGetConfigAttrib( mDisplay, mConfig, EGL_NATIVE_VISUAL_ID, &format ); ANativeWindow_setBuffersGeometry( nativeWindow, 0, 0, format ); mSurface = eglCreateWindowSurface( mDisplay, mConfig, nativeWindow, NULL ); auto err = eglGetError(); if( err != EGL_SUCCESS ) { return false; } EGLint contextAttibutes[] = { #if defined( CINDER_GL_ES_3 ) EGL_CONTEXT_CLIENT_VERSION, 3, #else EGL_CONTEXT_CLIENT_VERSION, 2, #endif EGL_NONE }; mContext = eglCreateContext( mDisplay, mConfig, NULL, contextAttibutes ); if( eglGetError() != EGL_SUCCESS ) { return false; } checkGlStatus(); eglMakeCurrent( mDisplay, mSurface, mSurface, mContext ); if( eglGetError() != EGL_SUCCESS ) { return false; } checkGlStatus(); gl::Environment::setEs(); gl::env()->initializeFunctionPointers(); checkGlStatus(); std::shared_ptr<gl::PlatformDataAndroid> platformData( new gl::PlatformDataAndroid( mContext, mDisplay, mSurface, mConfig ) ); platformData->mObjectTracking = mRenderer->getOptions().getObjectTracking(); mCinderContext = gl::Context::createFromExisting( platformData ); checkGlStatus(); // Get device screen size { EGLint width; EGLint height; eglQuerySurface( mDisplay, mSurface, EGL_WIDTH, &width ); eglQuerySurface( mDisplay, mSurface, EGL_HEIGHT, &height ); RendererGlAndroid::sSurfaceSize = ivec2( width, height ); } mCinderContext->makeCurrent(); checkGlStatus(); // NOTE: 'interval' value of 0 causes the Samsung S6 to not render correctly on startup. // eglSwapInterval( mDisplay, 1 ); checkGlStatus(); return true; }
void GlContext::create(uint32_t _width, uint32_t _height) { # if BX_PLATFORM_RPI bcm_host_init(); # endif // BX_PLATFORM_RPI m_eglLibrary = eglOpen(); if (NULL == g_platformData.context) { # if BX_PLATFORM_RPI g_platformData.ndt = EGL_DEFAULT_DISPLAY; # endif // BX_PLATFORM_RPI BX_UNUSED(_width, _height); EGLNativeDisplayType ndt = (EGLNativeDisplayType)g_platformData.ndt; EGLNativeWindowType nwh = (EGLNativeWindowType )g_platformData.nwh; # if BX_PLATFORM_WINDOWS if (NULL == g_platformData.ndt) { ndt = GetDC( (HWND)g_platformData.nwh); } # endif // BX_PLATFORM_WINDOWS m_display = eglGetDisplay(ndt); BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display); EGLint major = 0; EGLint minor = 0; EGLBoolean success = eglInitialize(m_display, &major, &minor); BGFX_FATAL(success && major >= 1 && minor >= 3, Fatal::UnableToInitialize, "Failed to initialize %d.%d", major, minor); BX_TRACE("EGL info:"); const char* clientApis = eglQueryString(m_display, EGL_CLIENT_APIS); BX_TRACE(" APIs: %s", clientApis); BX_UNUSED(clientApis); const char* vendor = eglQueryString(m_display, EGL_VENDOR); BX_TRACE(" Vendor: %s", vendor); BX_UNUSED(vendor); const char* version = eglQueryString(m_display, EGL_VERSION); BX_TRACE("Version: %s", version); BX_UNUSED(version); const char* extensions = eglQueryString(m_display, EGL_EXTENSIONS); BX_TRACE("Supported EGL extensions:"); dumpExtensions(extensions); EGLint attrs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, # if BX_PLATFORM_ANDROID EGL_DEPTH_SIZE, 16, # else EGL_DEPTH_SIZE, 24, # endif // BX_PLATFORM_ EGL_STENCIL_SIZE, 8, EGL_NONE }; EGLint numConfig = 0; success = eglChooseConfig(m_display, attrs, &m_config, 1, &numConfig); BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig"); # if BX_PLATFORM_ANDROID EGLint format; eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format); ANativeWindow_setBuffersGeometry( (ANativeWindow*)g_platformData.nwh, _width, _height, format); # elif BX_PLATFORM_RPI DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0); DISPMANX_UPDATE_HANDLE_T dispmanUpdate = vc_dispmanx_update_start(0); VC_RECT_T dstRect = { 0, 0, int32_t(_width), int32_t(_height) }; VC_RECT_T srcRect = { 0, 0, int32_t(_width) << 16, int32_t(_height) << 16 }; DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate , dispmanDisplay , 0 , &dstRect , 0 , &srcRect , DISPMANX_PROTECTION_NONE , NULL , NULL , DISPMANX_NO_ROTATE ); s_dispmanWindow.element = dispmanElement; s_dispmanWindow.width = _width; s_dispmanWindow.height = _height; nwh = &s_dispmanWindow; vc_dispmanx_update_submit_sync(dispmanUpdate); # endif // BX_PLATFORM_ANDROID m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL); BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface."); const bool hasEglKhrCreateContext = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context"); const bool hasEglKhrNoError = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context_no_error"); for (uint32_t ii = 0; ii < 2; ++ii) { bx::StaticMemoryBlockWriter writer(s_contextAttrs, sizeof(s_contextAttrs) ); EGLint flags = 0; # if BX_PLATFORM_RPI BX_UNUSED(hasEglKhrCreateContext, hasEglKhrNoError); #else if (hasEglKhrCreateContext) { bx::write(&writer, EGLint(EGL_CONTEXT_MAJOR_VERSION_KHR) ); bx::write(&writer, EGLint(BGFX_CONFIG_RENDERER_OPENGLES / 10) ); bx::write(&writer, EGLint(EGL_CONTEXT_MINOR_VERSION_KHR) ); bx::write(&writer, EGLint(BGFX_CONFIG_RENDERER_OPENGLES % 10) ); flags |= BGFX_CONFIG_DEBUG && hasEglKhrNoError ? 0 | EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR : 0 ; if (0 == ii) { flags |= BGFX_CONFIG_DEBUG ? 0 | EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR // | EGL_OPENGL_ES3_BIT_KHR : 0 ; bx::write(&writer, EGLint(EGL_CONTEXT_FLAGS_KHR) ); bx::write(&writer, flags); } } else # endif // BX_PLATFORM_RPI { bx::write(&writer, EGLint(EGL_CONTEXT_CLIENT_VERSION) ); bx::write(&writer, 2); } bx::write(&writer, EGLint(EGL_NONE) ); m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, s_contextAttrs); if (NULL != m_context) { break; } BX_TRACE("Failed to create EGL context with EGL_CONTEXT_FLAGS_KHR (%08x).", flags); } BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::UnableToInitialize, "Failed to create context."); success = eglMakeCurrent(m_display, m_surface, m_surface, m_context); BGFX_FATAL(success, Fatal::UnableToInitialize, "Failed to set context."); m_current = NULL; eglSwapInterval(m_display, 0); } import(); }
int main(int argc, char *argv[]) { EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); assert(display != EGL_NO_DISPLAY); assert(eglGetError() == EGL_SUCCESS); EGLint major = 0, minor = 0; EGLBoolean ret = eglInitialize(display, &major, &minor); assert(eglGetError() == EGL_SUCCESS); assert(ret == EGL_TRUE); assert(major * 10000 + minor >= 10004); EGLint numConfigs; ret = eglGetConfigs(display, NULL, 0, &numConfigs); assert(eglGetError() == EGL_SUCCESS); assert(ret == EGL_TRUE); EGLint attribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_NONE }; EGLConfig config; ret = eglChooseConfig(display, attribs, &config, 1, &numConfigs); assert(eglGetError() == EGL_SUCCESS); assert(ret == EGL_TRUE); EGLNativeWindowType dummyWindow; EGLSurface surface = eglCreateWindowSurface(display, config, dummyWindow, NULL); assert(eglGetError() == EGL_SUCCESS); assert(surface != 0); // WebGL maps to GLES2. GLES1 is not supported. EGLint contextAttribsOld[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; EGLContext context = eglCreateContext(display, config, NULL, contextAttribsOld); assert(eglGetError() != EGL_SUCCESS); //Test for invalid attribs EGLint contextInvalidAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, 0xFFFF, -1, EGL_NONE }; context = eglCreateContext(display, config, NULL, contextInvalidAttribs); assert(eglGetError() != EGL_SUCCESS); assert(context == 0); //Test for missing terminator EGLint contextAttribsMissingTerm[] = { EGL_CONTEXT_CLIENT_VERSION, 2, }; context = eglCreateContext(display, config, NULL, contextAttribsMissingTerm); assert(eglGetError() != EGL_SUCCESS); assert(context == 0); //Test for null terminator EGLint contextAttribsNullTerm[] = { EGL_CONTEXT_CLIENT_VERSION, 2, 0 }; context = eglCreateContext(display, config, NULL, contextAttribsNullTerm); assert(eglGetError() != EGL_SUCCESS); assert(context == 0); //Test for invalid and null terminator EGLint contextAttribsNullTermInvalid[] = { 0, }; context = eglCreateContext(display, config, NULL, contextAttribsNullTermInvalid); assert(eglGetError() != EGL_SUCCESS); assert(context == 0); // The correct attributes, should create a good EGL context EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; context = eglCreateContext(display, config, NULL, contextAttribs); assert(eglGetError() == EGL_SUCCESS); assert(context != 0); assert(eglGetCurrentContext() == 0); // Creating a context does not yet activate it. assert(eglGetError() == EGL_SUCCESS); ret = eglMakeCurrent(display, surface, surface, context); assert(eglGetError() == EGL_SUCCESS); assert(ret == EGL_TRUE); assert(eglGetCurrentContext() == context); assert(eglGetCurrentSurface(EGL_READ) == surface); assert(eglGetCurrentSurface(EGL_DRAW) == surface); glClearColor(1.0,0.0,0.0,0.5); glClear(GL_COLOR_BUFFER_BIT); ret = eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); assert(eglGetError() == EGL_SUCCESS); assert(ret == EGL_TRUE); assert(eglGetCurrentContext() == EGL_NO_CONTEXT); assert(eglGetCurrentSurface(EGL_READ) == EGL_NO_SURFACE); assert(eglGetCurrentSurface(EGL_DRAW) == EGL_NO_SURFACE); assert(eglSwapInterval(display, 0) == EGL_TRUE); assert(eglGetError() == EGL_SUCCESS); assert(eglSwapInterval(display, 1) == EGL_TRUE); assert(eglGetError() == EGL_SUCCESS); assert(eglSwapInterval(display, 2) == EGL_TRUE); assert(eglGetError() == EGL_SUCCESS); ret = eglTerminate(display); assert(eglGetError() == EGL_SUCCESS); assert(ret == EGL_TRUE); // eglGetProcAddress() without active GL context and/or connected EGL display (after eglTerminate) is required to work, even though the returned function // pointers cannot be called unless an active context is available: // "return value of NULL indicates that the specified function does not exist for the implementation." // "Client API function pointers returned by eglGetProcAddress are independent of the display and the currently bound client API context, and may be used by any client API context which supports the function." // At https://www.khronos.org/registry/EGL/specs/eglspec.1.5.pdf, pages 82-32. assert(eglGetProcAddress("glClear") != 0); assert(eglGetProcAddress("glWakaWaka") == 0); #ifdef REPORT_RESULT REPORT_RESULT(result); #endif }
/* Must be called in the gl thread */ GstGLWindow * gst_gl_window_new (gulong external_gl_context) { GstGLWindow *window = g_object_new (GST_GL_TYPE_WINDOW, NULL); GstGLWindowPrivate *priv = window->priv; EGLint config_attrib[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_DEPTH_SIZE, 16, EGL_NONE }; EGLint context_attrib[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLint majorVersion; EGLint minorVersion; EGLint numConfigs; EGLConfig config; XSetWindowAttributes win_attr; XTextProperty text_property; XWMHints wm_hints; unsigned long mask; const gchar *title = "OpenGL renderer"; Atom wm_atoms[3]; static gint x = 0; static gint y = 0; setlocale (LC_NUMERIC, "C"); priv->x_lock = g_mutex_new (); priv->cond_send_message = g_cond_new (); priv->running = TRUE; priv->visible = FALSE; priv->parent = 0; priv->allow_extra_expose_events = TRUE; g_mutex_lock (priv->x_lock); priv->device = XOpenDisplay (priv->display_name); XSynchronize (priv->device, FALSE); g_debug ("gl device id: %ld\n", (gulong) priv->device); priv->disp_send = XOpenDisplay (priv->display_name); XSynchronize (priv->disp_send, FALSE); g_debug ("gl display sender: %ld\n", (gulong) priv->disp_send); priv->screen_num = DefaultScreen (priv->device); priv->root = RootWindow (priv->device, priv->screen_num); priv->depth = DefaultDepth (priv->device, priv->screen_num); g_debug ("gl root id: %lud\n", (gulong) priv->root); priv->device_width = DisplayWidth (priv->device, priv->screen_num); priv->device_height = DisplayHeight (priv->device, priv->screen_num); priv->visual_info = g_new0 (XVisualInfo, 1); XMatchVisualInfo (priv->device, priv->screen_num, priv->depth, TrueColor, priv->visual_info); win_attr.event_mask = StructureNotifyMask | ExposureMask | VisibilityChangeMask; win_attr.do_not_propagate_mask = NoEventMask; win_attr.background_pixmap = None; win_attr.background_pixel = 0; win_attr.border_pixel = 0; win_attr.colormap = XCreateColormap (priv->device, priv->root, priv->visual_info->visual, AllocNone); mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask; x += 20; y += 20; priv->internal_win_id = XCreateWindow (priv->device, priv->root, x, y, 1, 1, 0, priv->visual_info->depth, InputOutput, priv->visual_info->visual, mask, &win_attr); if (!priv->internal_win_id) { g_debug ("XCreateWindow failed\n"); goto failure; } XSync (priv->device, FALSE); XSetWindowBackgroundPixmap (priv->device, priv->internal_win_id, None); g_debug ("gl window id: %lud\n", (gulong) priv->internal_win_id); g_debug ("gl window props: x:%d y:%d\n", x, y); wm_atoms[0] = XInternAtom (priv->device, "WM_DELETE_WINDOW", True); if (wm_atoms[0] == None) g_debug ("Cannot create WM_DELETE_WINDOW\n"); wm_atoms[1] = XInternAtom (priv->device, "WM_GL_WINDOW", False); if (wm_atoms[1] == None) g_debug ("Cannot create WM_GL_WINDOW\n"); wm_atoms[2] = XInternAtom (priv->device, "WM_QUIT_LOOP", False); if (wm_atoms[2] == None) g_debug ("Cannot create WM_QUIT_LOOP\n"); XSetWMProtocols (priv->device, priv->internal_win_id, wm_atoms, 2); wm_hints.flags = StateHint; wm_hints.initial_state = NormalState; wm_hints.input = False; XStringListToTextProperty ((char **) &title, 1, &text_property); XSetWMProperties (priv->device, priv->internal_win_id, &text_property, &text_property, 0, 0, NULL, &wm_hints, NULL); XFree (text_property.value); priv->gl_display = eglGetDisplay ((EGLNativeDisplayType) priv->device); if (eglInitialize (priv->gl_display, &majorVersion, &minorVersion)) g_debug ("egl initialized: %d.%d\n", majorVersion, minorVersion); else { g_debug ("failed to initialize egl %ld, %s\n", (gulong) priv->gl_display, EGLErrorString ()); goto failure; } if (eglChooseConfig (priv->gl_display, config_attrib, &config, 1, &numConfigs)) g_debug ("config set: %ld, %ld\n", (gulong) config, (gulong) numConfigs); else { g_debug ("failed to set config %ld, %s\n", (gulong) priv->gl_display, EGLErrorString ()); goto failure; } priv->gl_surface = eglCreateWindowSurface (priv->gl_display, config, (EGLNativeWindowType) priv->internal_win_id, NULL); if (priv->gl_surface != EGL_NO_SURFACE) g_debug ("surface created: %ld\n", (gulong) priv->gl_surface); else { g_debug ("failed to create surface %ld, %ld, %ld, %s\n", (gulong) priv->gl_display, (gulong) priv->gl_surface, (gulong) priv->gl_display, EGLErrorString ()); goto failure; } g_debug ("about to create gl context\n"); priv->gl_context = eglCreateContext (priv->gl_display, config, (EGLContext) (guint) external_gl_context, context_attrib); if (priv->gl_context != EGL_NO_CONTEXT) g_debug ("gl context created: %ld\n", (gulong) priv->gl_context); else { g_debug ("failed to create glcontext %ld, %ld, %s\n", (gulong) priv->gl_context, (gulong) priv->gl_display, EGLErrorString ()); goto failure; } if (!eglMakeCurrent (priv->gl_display, priv->gl_surface, priv->gl_surface, priv->gl_context)) { g_debug ("failed to make opengl context current %ld, %s\n", (gulong) priv->gl_display, EGLErrorString ()); goto failure; } g_mutex_unlock (priv->x_lock); return window; failure: g_mutex_unlock (priv->x_lock); g_object_unref (G_OBJECT (window)); return NULL; }
/***************************************************************************** * Function Name : ApiInitAPI * Returns : true for success * Description : Initialise the 3D API *****************************************************************************/ bool PVRShellInit::ApiInitAPI() { int bDone; m_NDT = (EGLNativeDisplayType)OsGetNativeDisplayType(); m_NPT = (EGLNativePixmapType) OsGetNativePixmapType(); m_NWT = (EGLNativeWindowType) OsGetNativeWindowType(); m_EGLContext = 0; do { bDone = true; m_EGLDisplay = eglGetDisplay(m_NDT); if(m_EGLDisplay == EGL_NO_DISPLAY) { #if defined(BUILD_OGLES2) || defined(BUILD_OVG) || defined(BUILD_OGLES3) m_EGLDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY); #else m_EGLDisplay = eglGetDisplay((NativeDisplayType)EGL_DEFAULT_DISPLAY); #endif } if(!eglInitialize(m_EGLDisplay, &m_MajorVersion, &m_MinorVersion)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to initialise EGL\n"); m_pShell->PVRShellOutputDebug("PVRShell: EGL Error (%s)\n", StringFrom_eglGetError()); return false; } m_pShell->PVRShellOutputDebug("PVRShell: EGL %d.%d initialized\n", m_MajorVersion, m_MinorVersion); // Check Extension avaliablility after EGL initialization if (m_MajorVersion > 1 || (m_MajorVersion == 1 && m_MinorVersion >= 1)) { m_bPowerManagementSupported = true; } else { m_bPowerManagementSupported = PVRShellIsExtensionSupported(m_EGLDisplay,"EGL_IMG_power_management"); } do { // bind OpenVG API if requested if(m_pShell->m_pShellData->bNeedOpenVG) { #ifndef BUILD_OVG m_pShell->PVRShellSet(prefExitMessage, "PVRShell: OpenVG not supported. Compile with BUILD_OVG defined."); return false; #else if(!eglBindAPI(EGL_OPENVG_API)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to bind OpenVG API\n"); return false; } m_pShell->PVRShellOutputDebug("PVRShell: OpenVG bound\n"); #endif } else { #if defined(BUILD_OGL) if(!eglBindAPI(EGL_OPENGL_API)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to bind OpenGL API\n"); return false; } #else #if defined EGL_VERSION_1_3 && defined GL_ES_VERSION_2_0 if(!eglBindAPI(EGL_OPENGL_ES_API)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to bind OpenGL ES API\n"); return false; } #endif #endif } // Find an EGL config m_EGLConfig = SelectEGLConfiguration(m_pShell->m_pShellData); eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_CONFIG_ID, &m_iConfig); // Destroy the context if we already created one if (m_EGLContext) { eglDestroyContext(m_EGLDisplay, m_EGLContext); } // Attempt to create a context EGLint ai32ContextAttribs[32]; int i = 0; #if defined(EGL_VERSION_1_3) && defined(GL_ES_VERSION_2_0) ai32ContextAttribs[i++] = EGL_CONTEXT_CLIENT_VERSION; ai32ContextAttribs[i++] = 2; #endif #if defined(BUILD_OGLES2) || defined(BUILD_OGLES) || defined(BUILD_OGLES3) if(PVRShellIsExtensionSupported(m_EGLDisplay,"EGL_IMG_context_priority")) { ai32ContextAttribs[i++] = EGL_CONTEXT_PRIORITY_LEVEL_IMG; switch(m_pShell->PVRShellGet(prefPriority)) { case 0: ai32ContextAttribs[i++] = EGL_CONTEXT_PRIORITY_LOW_IMG; break; case 1: ai32ContextAttribs[i++] = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; break; default:ai32ContextAttribs[i++] = EGL_CONTEXT_PRIORITY_HIGH_IMG; } } #endif ai32ContextAttribs[i] = EGL_NONE; m_EGLContext = eglCreateContext(m_EGLDisplay, m_EGLConfig, NULL, ai32ContextAttribs); if(m_EGLContext == EGL_NO_CONTEXT) { if(m_iRequestedConfig > 0) { // We failed to create a context m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create a context\n"); return false; } else if(m_pShell->m_pShellData->bNeedPbuffer) { // Disable P-buffer and try again m_pShell->m_pShellData->bNeedPbuffer = false; } else if(m_pShell->m_pShellData->bNeedStencilBuffer) { // Disable Stencil Buffer and try again m_pShell->m_pShellData->bNeedStencilBuffer = false; } else if(m_pShell->m_pShellData->nFSAAMode > 0) { // Still failing, reduce the mode of AA and try again --m_pShell->m_pShellData->nFSAAMode; } else { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create a context\n"); return false; } } } while(m_EGLContext == EGL_NO_CONTEXT); #if defined(__QNXNTO__) int format = SCREEN_FORMAT_RGBX8888; if(screen_set_window_property_iv((_screen_window*) m_NWT, SCREEN_PROPERTY_FORMAT, &format)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to set window property SCREEN_PROPERTY_FORMAT\n"); return false; } #if defined(BUILD_OGLES2) int usage = SCREEN_USAGE_OPENGL_ES2; #else #if defined(BUILD_OGLES) int usage = SCREEN_USAGE_OPENGL_ES1; #else #if defined(BUILD_OVG) int usage = SCREEN_USAGE_OPENVG; #endif #endif #endif if(screen_set_window_property_iv((_screen_window*) m_NWT, SCREEN_PROPERTY_USAGE, &usage)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to set window property SCREEN_PROPERTY_USAGE\n"); return false; } if(screen_create_window_buffers((_screen_window*) m_NWT, 2)) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Failed to create window buffers\n"); return false; } #endif EGLint attrib_list[16]; int i = 0; #if defined(EGL_VERSION_1_2) if(m_pShell->m_pShellData->bNeedAlphaFormatPre) // The default is EGL_ALPHA_FORMAT_NONPRE { attrib_list[i++] = EGL_ALPHA_FORMAT; attrib_list[i++] = EGL_ALPHA_FORMAT_PRE; } #endif // Terminate the attribute list with EGL_NONE attrib_list[i] = EGL_NONE; if(m_pShell->m_pShellData->bNeedPixmap) { m_pShell->PVRShellOutputDebug("InitAPI() Using pixmaps, about to create egl surface\n"); m_EGLWindow = eglCreatePixmapSurface(m_EGLDisplay, m_EGLConfig, m_NPT, attrib_list); } else { #if defined(ANDROID) EGLint visualID; eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_NATIVE_VISUAL_ID, &visualID); // Change the format of our window to match our config ANativeWindow_setBuffersGeometry(m_NWT, 0, 0, visualID); #endif m_EGLWindow = eglCreateWindowSurface(m_EGLDisplay, m_EGLConfig, m_NWT, attrib_list); // If we have failed to create a surface then try using Null if(m_EGLWindow == EGL_NO_SURFACE) { m_EGLWindow = eglCreateWindowSurface(m_EGLDisplay, m_EGLConfig, NULL, attrib_list); } } if (m_EGLWindow == EGL_NO_SURFACE) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create surface\n"); return false; } if (!eglMakeCurrent(m_EGLDisplay, m_EGLWindow, m_EGLWindow, m_EGLContext)) { #ifdef EGL_VERSION_1_3 if((eglGetError() == EGL_CONTEXT_LOST)) #else if((eglGetError() == EGL_CONTEXT_LOST_IMG) && m_bPowerManagementSupported) #endif { bDone = false; } else { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to make context current\n"); return false; } } } while(!bDone); /* Get correct screen width and height and save them into m_pShell->m_pShellData->nShellDimX and m_pShell->m_pShellData->nShellDimY */ eglQuerySurface(m_EGLDisplay, m_EGLWindow, EGL_WIDTH, (EGLint*)&m_pShell->m_pShellData->nShellDimX ); eglQuerySurface(m_EGLDisplay, m_EGLWindow, EGL_HEIGHT, (EGLint*)&m_pShell->m_pShellData->nShellDimY ); #if defined(ANDROID) && !defined(BUILD_OVG) glViewport(0,0,m_pShell->m_pShellData->nShellDimX, m_pShell->m_pShellData->nShellDimY); #endif /* Done - activate requested features */ ApiActivatePreferences(); return true; }
static struct window *window_create(struct display *display, const char *name, unsigned int x, unsigned int y, unsigned int width, unsigned int height) { static const EGLint attribs[] = { EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_DEPTH_SIZE, 1, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; static const EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; XSetWindowAttributes attr; struct window *window; unsigned long mask; XVisualInfo visual; EGLint num_configs; XVisualInfo *info; XSizeHints hints; EGLConfig config; int num_visuals; EGLint version; Window root; int screen; EGLint vid; window = calloc(1, sizeof(*window)); if (!window) return NULL; window->display = display; screen = DefaultScreen(display->x11); root = RootWindow(display->x11, screen); if (!eglChooseConfig(display->egl, attribs, &config, 1, &num_configs)) { free(window); return NULL; } if (!eglGetConfigAttrib(display->egl, config, EGL_NATIVE_VISUAL_ID, &vid)) { free(window); return NULL; } visual.visualid = vid; info = XGetVisualInfo(display->x11, VisualIDMask, &visual, &num_visuals); if (!info) { free(window); return NULL; } memset(&attr, 0, sizeof(attr)); attr.background_pixel = 0; attr.border_pixel = 0; attr.colormap = XCreateColormap(display->x11, root, info->visual, AllocNone); attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; window->x11 = XCreateWindow(display->x11, root, 0, 0, width, height, 0, info->depth, InputOutput, info->visual, mask, &attr); if (!window->x11) { free(window); return NULL; } memset(&hints, 0, sizeof(hints)); hints.x = x; hints.y = y; hints.width = width; hints.height = height; hints.flags = USSize | USPosition; XSetNormalHints(display->x11, window->x11, &hints); XSetStandardProperties(display->x11, window->x11, name, name, None, NULL, 0, &hints); eglBindAPI(EGL_OPENGL_ES_API); window->context = eglCreateContext(display->egl, config, EGL_NO_CONTEXT, attrs); if (window->context == EGL_NO_CONTEXT) { free(window); return NULL; } eglQueryContext(display->egl, window->context, EGL_CONTEXT_CLIENT_VERSION, &version); printf("OpenGL ES: %d\n", version); window->surface = eglCreateWindowSurface(display->egl, config, window->x11, NULL); if (window->surface == EGL_NO_SURFACE) { free(window); return NULL; } XFree(info); window->width = width; window->height = height; return window; }