/** * Initialize an EGL context for the current display. */ EGLContext fghCreateNewContextEGL( SFG_Window* window ) { EGLContext context; EGLint ver = -1; EGLDisplay eglDisplay = fgDisplay.pDisplay.egl.Display; EGLConfig eglConfig = window->Window.pContext.egl.Config; /* On GLES, user specifies the target version with glutInitContextVersion */ EGLint attributes[32]; int where = 0; ATTRIB_VAL(EGL_CONTEXT_CLIENT_VERSION, fgState.MajorVersion); ATTRIB(EGL_NONE); context = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attributes); if (context == EGL_NO_CONTEXT) { fgWarning("Cannot initialize EGL context, err=%x\n", eglGetError()); fghContextCreationError(); } eglQueryContext(fgDisplay.pDisplay.egl.Display, context, EGL_CONTEXT_CLIENT_VERSION, &ver); if (ver != fgState.MajorVersion) fgError("Wrong GLES major version: %d\n", ver); return context; }
QString QGLInfo::reportEGLConfigInfo() const { #if !defined(QT_NO_EGL) QString d; QEglProperties props; EGLint count = 0; EGLDisplay dpy = eglGetCurrentDisplay(); EGLContext ctx = eglGetCurrentContext(); EGLint cfgnum = 0; if (eglQueryContext(dpy, ctx, EGL_CONFIG_ID, &cfgnum)) { d += QString("Window configuration in use: ") + QString::number(cfgnum) + QLatin1String("\n\n"); } if (!eglGetConfigs(dpy, 0, 0, &count) || count < 1) return d; EGLConfig *configs = new EGLConfig [count]; eglGetConfigs(dpy, configs, count, &count); for (EGLint index = 0; index < count; ++index) { props = QEglProperties(configs[index]); d += props.toString() + QLatin1String("\n\n"); } delete [] configs; return d; #else return QString(); #endif }
void EGLDevice::printEGLContext(EGLContext context) { EGLint value; eglQueryContext(_eglDisplay, context, EGL_CONFIG_ID, &value); std::cout << "Context EGL_CONFIG_ID is " << value << std::endl; eglQueryContext(_eglDisplay, context, EGL_CONTEXT_CLIENT_TYPE, &value); std::cout << "\tEGL_CONTEXT_CLIENT_TYPE is " << std::string((value == EGL_OPENVG_API) ? "EGL_OPENVG_API" : "EGL_OPENGL_ES_API") << std::endl; // eglQueryContext(_eglDisplay, context, EGL_CONTEXT_CLIENT_VERSION, &value); // log_debug("EGL_CONTEXT_CLIENT_VERSION is %d", value); eglQueryContext(_eglDisplay, context, EGL_RENDER_BUFFER, &value); std::cout << "\tEGL_RENDER_BUFFER is " << std::string((value == EGL_BACK_BUFFER) ? "EGL_BACK_BUFFER" : "EGL_SINGLE_BUFFER") << std::endl; }
/** * Initialize an EGL context for the current display. */ EGLContext fghCreateNewContextEGL( SFG_Window* window ) { EGLContext context; EGLDisplay eglDisplay = fgDisplay.pDisplay.egl.Display; EGLConfig eglConfig = window->Window.pContext.egl.Config; /* Ensure OpenGLES 2.0 context */ static const EGLint ctx_attribs[] = { #ifdef GL_ES_VERSION_2_0 EGL_CONTEXT_CLIENT_VERSION, 2, #elif GL_VERSION_ES_CM_1_0 || GL_VERSION_ES_CL_1_0 || GL_VERSION_ES_CM_1_1 || GL_VERSION_ES_CL_1_1 EGL_CONTEXT_CLIENT_VERSION, 1, #endif EGL_NONE }; context = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, ctx_attribs); if (context == EGL_NO_CONTEXT) { fgWarning("Cannot initialize EGL context, err=%x\n", eglGetError()); fghContextCreationError(); } EGLint ver = -1; eglQueryContext(fgDisplay.pDisplay.egl.Display, context, EGL_CONTEXT_CLIENT_VERSION, &ver); #ifdef GL_ES_VERSION_2_0 if (ver != 2) #else if (ver != 1) #endif fgError("Wrong GLES major version: %d\n", ver); return context; }
bool makeCurrent(Drawable *drawable, Context *context) { if (!drawable || !context) { return eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } else { EglDrawable *eglDrawable = static_cast<EglDrawable *>(drawable); EglContext *eglContext = static_cast<EglContext *>(context); EGLBoolean ok; ok = eglMakeCurrent(eglDisplay, eglDrawable->surface, eglDrawable->surface, eglContext->context); if (ok) { EGLint api; eglQueryContext(eglDisplay, eglContext->context, EGL_CONTEXT_CLIENT_TYPE, &api); eglDrawable->api = api; } return ok; } }
/* private native int _eglQueryContext ( int display , int ctx , int attribute , int [ ] value ) ; */ KNIEXPORT KNI_RETURNTYPE_INT Java_javax_microedition_khronos_egl_EGL10Impl__1eglQueryContext() { jint display = KNI_GetParameterAsInt(1); jint ctx = KNI_GetParameterAsInt(2); jint attribute = KNI_GetParameterAsInt(3); EGLint value; jint returnValue = EGL_FALSE; KNI_StartHandles(1); KNI_DeclareHandle(valueHandle); KNI_GetParameterAsObject(4, valueHandle); returnValue = (jint)eglQueryContext((EGLDisplay)display, (EGLContext)ctx, attribute, &value); #ifdef DEBUG printf("eglQueryContext(0x%x, 0x%x, %d, value<-%d) = %d\n", display, ctx, attribute, value, returnValue); #endif if ((returnValue == EGL_TRUE) && !KNI_IsNullHandle(valueHandle)) { KNI_SetIntArrayElement(valueHandle, 0, value); } KNI_EndHandles(); KNI_ReturnInt(returnValue); }
void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLContext *share) { if (!nativeHandle.canConvert<QEGLNativeContext>()) { qWarning("QEGLPlatformContext: Requires a QEGLNativeContext"); return; } QEGLNativeContext handle = nativeHandle.value<QEGLNativeContext>(); EGLContext context = handle.context(); if (!context) { qWarning("QEGLPlatformContext: No EGLContext given"); return; } // A context belonging to a given EGLDisplay cannot be used with another one. if (handle.display() != m_eglDisplay) { qWarning("QEGLPlatformContext: Cannot adopt context from different display"); return; } // Figure out the EGLConfig. EGLint value = 0; eglQueryContext(m_eglDisplay, context, EGL_CONFIG_ID, &value); EGLint n = 0; EGLConfig cfg; const EGLint attribs[] = { EGL_CONFIG_ID, value, EGL_NONE }; if (eglChooseConfig(m_eglDisplay, attribs, &cfg, 1, &n) && n == 1) { m_eglConfig = cfg; m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig); } else { qWarning("QEGLPlatformContext: Failed to get framebuffer configuration for context"); } // Fetch client API type. value = 0; eglQueryContext(m_eglDisplay, context, EGL_CONTEXT_CLIENT_TYPE, &value); if (value == EGL_OPENGL_API || value == EGL_OPENGL_ES_API) { m_api = value; eglBindAPI(m_api); } else { qWarning("QEGLPlatformContext: Failed to get client API type"); m_api = EGL_OPENGL_ES_API; } m_eglContext = context; m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0; updateFormatFromGL(); }
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengles_EGL_neglQueryContext(JNIEnv *env, jclass clazz, jlong dpy_ptr, jlong ctx_ptr, jint attribute, jlong value) { EGLDisplay dpy = (EGLDisplay)(intptr_t)dpy_ptr; EGLContext ctx = (EGLContext)(intptr_t)ctx_ptr; EGLint *value_address = (EGLint *)(intptr_t)value; return eglQueryContext(dpy, ctx, attribute, value_address); }
/* EGLBoolean eglQueryContext ( EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value ) */ static jboolean android_eglQueryContext (JNIEnv *_env, jobject _this, jobject dpy, jobject ctx, jint attribute, jintArray value_ref, jint offset) { jint _exception = 0; const char * _exceptionType = NULL; const char * _exceptionMessage = NULL; EGLBoolean _returnValue = (EGLBoolean) 0; EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy); EGLContext ctx_native = (EGLContext) fromEGLHandle(_env, eglcontextGetHandleID, ctx); EGLint *value_base = (EGLint *) 0; jint _remaining; EGLint *value = (EGLint *) 0; if (!value_ref) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "value == null"; goto exit; } if (offset < 0) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "offset < 0"; goto exit; } _remaining = _env->GetArrayLength(value_ref) - offset; if (_remaining < 1) { _exception = 1; _exceptionType = "java/lang/IllegalArgumentException"; _exceptionMessage = "length - offset < 1 < needed"; goto exit; } value_base = (EGLint *) _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0); value = value_base + offset; _returnValue = eglQueryContext( (EGLDisplay)dpy_native, (EGLContext)ctx_native, (EGLint)attribute, (EGLint *)value ); exit: if (value_base) { _env->ReleasePrimitiveArrayCritical(value_ref, value_base, _exception ? JNI_ABORT: 0); } if (_exception) { jniThrowException(_env, _exceptionType, _exceptionMessage); } return (jboolean)_returnValue; }
static EglConfig * egl_config_new_from_gl_context (EglDisplay * display, EGLContext gl_context) { EGLDisplay const gl_display = display->base.handle.p; EGLint attribs[3 * 2 + 1], *attrib = attribs; EGLint config_id, api, v; guint gles_version; const GlVersionInfo *vinfo; if (!eglQueryContext (gl_display, gl_context, EGL_CONFIG_ID, &config_id)) return NULL; if (!eglQueryContext (gl_display, gl_context, EGL_CONTEXT_CLIENT_TYPE, &api)) return NULL; if (!eglQueryContext (gl_display, gl_context, EGL_CONTEXT_CLIENT_VERSION, &v)) return NULL; if (api == EGL_OPENGL_API) gles_version = 0; else if (api == EGL_OPENGL_ES_API) gles_version = v; else { GST_ERROR ("unsupported EGL client API (%d)", api); return NULL; } vinfo = gl_version_info_lookup (gles_version); if (!vinfo) return NULL; *attrib++ = EGL_COLOR_BUFFER_TYPE; *attrib++ = EGL_RGB_BUFFER; *attrib++ = EGL_CONFIG_ID; *attrib++ = config_id; *attrib++ = EGL_RENDERABLE_TYPE; *attrib++ = vinfo->gl_api_bit; *attrib++ = EGL_NONE; g_assert (attrib - attribs <= G_N_ELEMENTS (attribs)); return egl_config_new_with_attribs (display, attribs); }
::EGLConfig EGLSupport::getGLConfigFromContext(::EGLContext context) { ::EGLConfig glConfig = 0; if (eglQueryContext(mGLDisplay, context, EGL_CONFIG_ID, (EGLint *) &glConfig) == EGL_FALSE) { OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Fail to get config from context", __FUNCTION__); return 0; } return glConfig; }
static jboolean jni_eglQueryContext(JNIEnv *_env, jobject _this, jobject display, jobject context, jint attribute, jintArray value) { if (display == NULL || context == NULL || value == NULL || _env->GetArrayLength(value) < 1) { jniThrowException(_env, "java/lang/IllegalArgumentException", NULL); return JNI_FALSE; } EGLDisplay dpy = getDisplay(_env, display); EGLContext ctx = getContext(_env, context); EGLBoolean success = EGL_FALSE; int len = _env->GetArrayLength(value); if (len) { jint* base = _env->GetIntArrayElements(value, (jboolean *)0); success = eglQueryContext(dpy, ctx, attribute, base); _env->ReleaseIntArrayElements(value, base, 0); } return EglBoolToJBool(success); }
static jboolean jni_eglQueryContext(JNIEnv *_env, jobject _this, jobject display, jobject context, jint attribute, jintArray value) { if (display == NULL || context == NULL || value == NULL || _env->GetArrayLength(value) < 1) { jniThrowException(_env, "java/lang/IllegalArgumentException", NULL); return JNI_FALSE; } EGLDisplay dpy = getDisplay(_env, display); EGLContext ctx = getContext(_env, context); jboolean success = JNI_FALSE; int len = _env->GetArrayLength(value); if (len) { jint* base = (jint *)_env->GetPrimitiveArrayCritical(value, (jboolean *)0); success = eglQueryContext(dpy, ctx, attribute, base); _env->ReleasePrimitiveArrayCritical(value, base, JNI_ABORT); } return success; }
/* * 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, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_DEPTH_SIZE, 24, 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; 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); } eglBindAPI(EGL_OPENGL_ES_API); 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; }
/*!*********************************************************************** @Function OutputAPIInfo @description When prefOutputInfo is set to true this function outputs various pieces of API dependent information via PVRShellOutputDebug. *************************************************************************/ void PVRShellInit::OutputAPIInfo() { // Output API dependent information if(m_pShell->PVRShellGet(prefOutputInfo)) { EGLint i32Values[5]; m_pShell->PVRShellOutputDebug("\n"); #ifndef BUILD_OVG m_pShell->PVRShellOutputDebug("GL:\n"); m_pShell->PVRShellOutputDebug(" Vendor: %s\n", (char*) glGetString(GL_VENDOR)); m_pShell->PVRShellOutputDebug(" Renderer: %s\n", (char*) glGetString(GL_RENDERER)); m_pShell->PVRShellOutputDebug(" Version: %s\n", (char*) glGetString(GL_VERSION)); #else m_pShell->PVRShellOutputDebug("VG:\n"); m_pShell->PVRShellOutputDebug(" Vendor: %s\n", (char*) vgGetString(VG_VENDOR)); m_pShell->PVRShellOutputDebug(" Renderer: %s\n", (char*) vgGetString(VG_RENDERER)); m_pShell->PVRShellOutputDebug(" Version: %s\n", (char*) vgGetString(VG_VERSION)); #endif m_pShell->PVRShellOutputDebug("\n"); m_pShell->PVRShellOutputDebug("EGL:\n"); m_pShell->PVRShellOutputDebug(" Vendor: %s\n" , (char*) eglQueryString(m_EGLDisplay, EGL_VENDOR)); m_pShell->PVRShellOutputDebug(" Version: %s\n" , (char*) eglQueryString(m_EGLDisplay, EGL_VERSION)); if(eglQueryContext(m_EGLDisplay, m_EGLContext, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &i32Values[0])) { switch(i32Values[0]) { case EGL_CONTEXT_PRIORITY_HIGH_IMG: m_pShell->PVRShellOutputDebug(" Context priority: High\n"); break; case EGL_CONTEXT_PRIORITY_MEDIUM_IMG: m_pShell->PVRShellOutputDebug(" Context priority: Medium\n");break; case EGL_CONTEXT_PRIORITY_LOW_IMG: m_pShell->PVRShellOutputDebug(" Context priority: Low\n"); break; default: m_pShell->PVRShellOutputDebug(" Context priority: Unrecognised.\n"); } } else { eglGetError(); // Clear error m_pShell->PVRShellOutputDebug(" Context priority: Unsupported\n"); } #ifdef EGL_VERSION_1_2 m_pShell->PVRShellOutputDebug(" Client APIs: %s\n" , (char*) eglQueryString(m_EGLDisplay, EGL_CLIENT_APIS)); #endif m_pShell->PVRShellOutputDebug("\n"); m_pShell->PVRShellOutputDebug("Window Width: %i\n" , m_pShell->PVRShellGet(prefWidth)); m_pShell->PVRShellOutputDebug("Window Height: %i\n" , m_pShell->PVRShellGet(prefHeight)); m_pShell->PVRShellOutputDebug("Is Rotated: %s\n", m_pShell->PVRShellGet(prefIsRotated) ? "Yes" : "No"); m_pShell->PVRShellOutputDebug("\n"); // EGLSurface details m_pShell->PVRShellOutputDebug("EGL Surface:\n"); eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_CONFIG_ID , &i32Values[0]); m_pShell->PVRShellOutputDebug(" Config ID: %i\n", i32Values[0]); // Colour buffer eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_BUFFER_SIZE , &i32Values[0]); eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_RED_SIZE , &i32Values[1]); eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_GREEN_SIZE , &i32Values[2]); eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_BLUE_SIZE , &i32Values[3]); eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_ALPHA_SIZE , &i32Values[4]); m_pShell->PVRShellOutputDebug(" Colour Buffer: %i bits (R%i G%i B%i A%i)\n", i32Values[0],i32Values[1],i32Values[2],i32Values[3],i32Values[4]); // Depth buffer eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_DEPTH_SIZE , &i32Values[0]); m_pShell->PVRShellOutputDebug(" Depth Buffer: %i bits\n", i32Values[0]); // Stencil Buffer eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_STENCIL_SIZE , &i32Values[0]); m_pShell->PVRShellOutputDebug(" Stencil Buffer: %i bits\n", i32Values[0]); // EGL surface bits support eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_SURFACE_TYPE , &i32Values[0]); m_pShell->PVRShellOutputDebug(" Surface type: %s%s%s\n", i32Values[0] & EGL_WINDOW_BIT ? "WINDOW " : "", i32Values[1] & EGL_PBUFFER_BIT ? "PBUFFER " : "", i32Values[2] & EGL_PIXMAP_BIT ? "PIXMAP " : ""); // EGL renderable type #ifdef EGL_VERSION_1_2 eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_RENDERABLE_TYPE , &i32Values[0]); m_pShell->PVRShellOutputDebug(" Renderable type: %s%s%s%s\n", i32Values[0] & EGL_OPENVG_BIT ? "OPENVG " : "", i32Values[0] & EGL_OPENGL_ES_BIT ? "OPENGL_ES " : "", #ifdef EGL_OPENGL_BIT i32Values[0] & EGL_OPENGL_BIT ? "OPENGL " : #endif "", i32Values[0] & EGL_OPENGL_ES2_BIT ? "OPENGL_ES2 " : ""); #endif #ifndef BUILD_OVG eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_SAMPLE_BUFFERS , &i32Values[0]); eglGetConfigAttrib(m_EGLDisplay, m_EGLConfig, EGL_SAMPLES , &i32Values[1]); m_pShell->PVRShellOutputDebug(" Sample buffer No.: %i\n", i32Values[0]); m_pShell->PVRShellOutputDebug(" Samples per pixel: %i\n", i32Values[1]); #else m_pShell->PVRShellOutputDebug("\n"); switch(vgGeti(VG_RENDERING_QUALITY)) { case VG_RENDERING_QUALITY_BETTER: m_pShell->PVRShellOutputDebug("Rendering quality: VG_RENDERING_QUALITY_BETTER\n"); break; case VG_RENDERING_QUALITY_FASTER: m_pShell->PVRShellOutputDebug("Rendering quality: VG_RENDERING_QUALITY_FASTER\n"); break; default: m_pShell->PVRShellOutputDebug("Rendering quality: VG_RENDERING_QUALITY_NONANTIALIASED\n"); } #endif } }
void DirectRender::InitForCurrentSurface( JNIEnv * jni, bool wantFrontBuffer_, int buildVersionSDK_ ) { LOG( "%p DirectRender::InitForCurrentSurface(%s)", this, wantFrontBuffer_ ? "true" : "false" ); wantFrontBuffer = wantFrontBuffer_; display = eglGetDisplay( EGL_DEFAULT_DISPLAY ); context = eglGetCurrentContext(); windowSurface = eglGetCurrentSurface( EGL_DRAW ); // NOTE: On Mali as well as under Android-L, we need to perform // an initial swapbuffers in order for the front-buffer extension // to work. // TODO: In previous KitKat development binaries, applying the initial // swapbuffers on Adreno would result in poor performance. We should // review if the issue still exists on the final production binary // and if not, remove the check for KitKat and always perform the // initial swapbuffers. static const int KITKAT_WATCH = 20; const GpuType gpuType = EglGetGpuType(); if ( ( buildVersionSDK_ > KITKAT_WATCH ) || // if the SDK is Lollipop or higher ( gpuType & GPU_TYPE_MALI ) != 0 ) // or the GPU is Mali { LOG( "Performing an initial swapbuffers for Mali and/or Android-L" ); eglSwapBuffers( display, windowSurface ); // swap buffer will operate que/deque related process internally // now ready to set usage to proper surface } // Get the surface size. eglQuerySurface( display, windowSurface, EGL_WIDTH, &width ); eglQuerySurface( display, windowSurface, EGL_HEIGHT, &height ); LOG( "surface size: %i x %i", width, height ); if ( !wantFrontBuffer_ ) { LOG( "Running without front buffer"); } else { surfaceMgr.Init( jni ); gvrFrontbufferExtension = surfaceMgr.SetFrontBuffer( windowSurface, true ); LOG ( "gvrFrontbufferExtension = %s", ( gvrFrontbufferExtension ) ? "TRUE" : "FALSE" ); if ( ( gpuType & GPU_TYPE_MALI ) != 0 ) { LOG( "Mali GPU" ); tilerControl = FB_MALI; } else if ( ( gpuType & GPU_TYPE_ADRENO ) != 0 ) { // Query the number of samples on the display EGLint configID; if ( !eglQueryContext( display, context, EGL_CONFIG_ID, &configID ) ) { FAIL( "eglQueryContext EGL_CONFIG_ID failed" ); } EGLConfig eglConfig = EglConfigForConfigID( display, configID ); if ( eglConfig == NULL ) { FAIL( "EglConfigForConfigID failed" ); } EGLint samples = 0; eglGetConfigAttrib( display, eglConfig, EGL_SAMPLES, &samples ); if ( gpuType == GPU_TYPE_ADRENO_330 ) { LOG( "Adreno 330 GPU" ); tilerControl = FB_TILED_RENDERING; } else { LOG( "Adreno GPU" ); // NOTE: On KitKat, only tiled render mode will continue to work // with multisamples set on the frame buffer (at a performance // loss). On Lollipop, having multisamples set on the frame buffer // is an error for all render modes and will result in a black screen. if ( samples != 0 ) { // TODO: We may want to make this a FATAL ERROR. LOG( "**********************************************" ); LOG( "ERROR: frame buffer uses MSAA - turn off MSAA!" ); LOG( "**********************************************" ); tilerControl = FB_TILED_RENDERING; } else { // NOTE: Currently (2014-11-19) the memory controller // clock is not fixed when running with fixed CPU/GPU levels. // For direct render mode, the fluctuation may cause significant // performance issues. // FIXME: Enable tiled render mode for now until we are able // to run with fixed memory clock. #if 0 tilerControl = FB_BINNING_CONTROL; // 2014-09-28: Qualcomm is moving to a new extension with // the next driver. In order for the binning control to // work for both the current and next driver, we add the // following call which should happen before any calls to // glHint( GL_* ). // This causes a gl error on current drivers, but will be // needed for the new driver. GL_CheckErrors( "Before enabling Binning Control" ); LOG( "Enable GL_BINNING_CONTROL_HINT_QCOM - may cause a GL_ERROR on current driver" ); glEnable( GL_BINNING_CONTROL_HINT_QCOM ); GL_CheckErrors( "Expected on current driver" ); #else tilerControl = FB_TILED_RENDERING; #endif } } } // draw stuff to the screen without swapping to see if it is working // ExerciseFrontBuffer(); } }
static struct gbm_context * stereo_prepare_context(struct gbm_dev *dev, const struct gbm_options *options) { struct gbm_context *context; EGLint multiview_view_count = 0; context = xmalloc(sizeof(*context)); context->dev = dev; context->gbm = gbm_create_device(dev->fd); if (context->gbm == NULL) { fprintf(stderr, "error creating GBM device\n"); goto error; } context->edpy = eglGetDisplay((EGLNativeDisplayType) context->gbm); if (context->edpy == EGL_NO_DISPLAY) { fprintf(stderr, "error getting EGL display\n"); goto error_gbm_device; } if (!eglInitialize(context->edpy, NULL, NULL)) { fprintf(stderr, "error intializing EGL display\n"); goto error_gbm_device; } if (!extension_supported(context->edpy, MULTIVIEW_WINDOW_EXTENSION)) { fprintf(stderr, MULTIVIEW_WINDOW_EXTENSION " not supported\n"); goto error_egl_display; } if (create_gbm_surface(context)) goto error_egl_display; if (choose_egl_config(context)) goto error_gbm_surface; if (create_egl_surface(context, options)) goto error_gbm_surface; if (create_egl_context(context)) goto error_egl_surface; if (!eglMakeCurrent(context->edpy, context->egl_surface, context->egl_surface, context->egl_context)) { fprintf(stderr, "failed to make EGL context current\n"); goto error_egl_context; } if ((!eglQueryContext(context->edpy, context->egl_context, EGL_MULTIVIEW_VIEW_COUNT_EXT, &multiview_view_count) || multiview_view_count < 2)) { fprintf(stderr, "EGL created a multiview surface with only %i %s\n", multiview_view_count, multiview_view_count == 1 ? "view" : "views"); goto error_unbind; } return context; error_unbind: eglMakeCurrent(context->edpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); error_egl_context: eglDestroyContext(context->edpy, context->egl_context); error_egl_surface: eglDestroySurface(context->edpy, context->egl_surface); error_gbm_surface: gbm_surface_destroy(context->gbm_surface); error_egl_display: eglTerminate(context->edpy); error_gbm_device: gbm_device_destroy(context->gbm); error: free(context); return NULL; }
static enum piglit_result check_flavor(int requested_version, enum gl_api requested_api) { static bool is_dispatch_init = false; enum piglit_result result = PIGLIT_PASS; int i; const char *api_name = NULL; const char *profile_name = ""; EGLint context_attribs[64]; EGLContext ctx = 0; EGLenum requested_client_type = 0; EGLint actual_client_type = 0; int actual_version = 0; GLint actual_profile = 0; switch (requested_api) { case API_GL_COMPAT: requested_client_type = EGL_OPENGL_API; api_name = "OpenGL"; if (requested_version >= 32) profile_name = "compatibility "; break; case API_GL_CORE: requested_client_type = EGL_OPENGL_API; api_name = "OpenGL"; if (requested_version >= 32) profile_name = "core "; break; case API_GLES1: case API_GLES2: case API_GLES3: requested_client_type = EGL_OPENGL_ES_API; api_name = "OpenGL ES"; break; default: assert(0); break; } printf("info: request an %s %d.%d %scontext\n", api_name, requested_version / 10, requested_version % 10, profile_name); if (!eglBindAPI(requested_client_type)) { /* Assume the driver doesn't support the requested API. */ result = PIGLIT_SKIP; goto cleanup; } i = 0; context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR; context_attribs[i++] = requested_version / 10; context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR; context_attribs[i++] = requested_version % 10; if (requested_api == API_GL_CORE) { context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; context_attribs[i++] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; } else if (requested_api == API_GL_COMPAT) { context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; context_attribs[i++] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; } context_attribs[i++] = EGL_NONE; ctx = eglCreateContext(egl_dpy, cfg, EGL_NO_CONTEXT, context_attribs); if (ctx == NULL) { printf("%s", "info: context creation failed\n"); if (eglGetError() != EGL_SUCCESS) { result = PIGLIT_SKIP; } else { printf("%s", "error: eglCreateContext failed but " "the EGL error is EGL_SUCCESS\n"); result = PIGLIT_FAIL; } goto cleanup; } if (!piglit_check_egl_error(EGL_SUCCESS)) { result = PIGLIT_FAIL; goto cleanup; } if (!eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx)) { printf("%s", "error: failed to make context current\n"); goto fail; } if (!is_dispatch_init) { /* We must postpone initialization of piglit-dispatch until * a context is current. */ piglit_dispatch_default_init(PIGLIT_DISPATCH_GL); is_dispatch_init = true; } if (!eglQueryContext(egl_dpy, ctx, EGL_CONTEXT_CLIENT_TYPE, &actual_client_type)) { printf("%s", "error: eglQueryContext(EGL_CONTEXT_CLIENT_TYPE) " "failed\n"); goto fail; } if (actual_client_type != requested_client_type) { printf("error: requested a context with EGL_CONTEXT_CLIENT_TYPE=0x%x " "but received one with EGL_CONTEXT_CLIENT_TYPE=0x%x.\n", requested_client_type, actual_client_type); goto fail; } actual_version = get_gl_version(); if (actual_version < requested_version) { printf("error: requested context version %d.%d but received " "version %d.%d\n", requested_version / 10, requested_version % 10, actual_version / 10, actual_version % 10); goto fail; } if (requested_api == API_GL_CORE || (requested_api == API_GL_COMPAT && requested_version >= 32)) { my_glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &actual_profile); if (!piglit_check_gl_error(GL_NO_ERROR)) { printf("%s", "error: glGetIntegerv(GL_CONTEXT_PROFILE_MASK)" "failed\n"); goto fail; } } if (requested_api == API_GL_CORE) { assert(requested_version >= 32); if (actual_profile != EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) { printf("error: requested an OpenGL %d.%d core context, " "but received a context whose profile " "mask is 0x%x.\n", requested_version / 10, requested_version % 10, actual_profile); goto fail; } } else if (requested_api == API_GL_COMPAT && requested_version >= 32) { if (actual_profile != EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR) { printf("error: requested an OpenGL %d.%d compatibility context, " "but received a context whose profile " "mask is 0x%x.\n", requested_version / 10, requested_version % 10, actual_profile); goto fail; } } else if (requested_api == API_GLES1) { if (actual_version > 11) { printf("error: requested an OpenGL ES %d.%d context, " "but received %d.%d context.\n", requested_version / 10, requested_version % 10, actual_version / 10, actual_version % 10); goto fail; } } else if (requested_api == API_GLES2) { /* Nothing special to check. */ } result = PIGLIT_PASS; goto cleanup; fail: result = PIGLIT_FAIL; goto cleanup; cleanup: /* We must unbind the context here due to a subtle requirement in the * EGL 1.4 spec published on 2011-04-06. The call to eglMakeCurrent at * the top of this function may attempt to bind a context whose api * differs from the api of the current context. Yet, according to the * EGL spec, it is illegal to bind a GL context to a surface if an ES * context is currently bound to it, and vice versa. * * A future revision of the EGL 1.4 spec will fix this non-intuitive * requirement. */ if (!eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { printf("%s", "error: failed to unbind any current context\n"); piglit_report_result(PIGLIT_FAIL); } switch (result) { case PIGLIT_PASS: printf("%s", "info: pass\n"); break; case PIGLIT_FAIL: printf("%s", "info: fail\n"); break; case PIGLIT_SKIP: printf("%s", "info: skip\n"); break; case PIGLIT_WARN: default: assert(0); break; } return result; }
eglSetup_t EglSetup( const EGLContext shareContext, const int requestedGlEsVersion, const int redBits, const int greenBits, const int blueBits, const int depthBits, const int multisamples, const GLuint contextPriority ) { LOG( "EglSetup: requestGlEsVersion(%d), redBits(%d), greenBits(%d), blueBits(%d), depthBits(%d), multisamples(%d), contextPriority(%d)", requestedGlEsVersion, redBits, greenBits, blueBits, depthBits, multisamples, contextPriority ); eglSetup_t egl = {}; // Get the built in display // TODO: check for external HDMI displays egl.display = eglGetDisplay( EGL_DEFAULT_DISPLAY ); // Initialize EGL EGLint majorVersion; EGLint minorVersion; eglInitialize( egl.display, &majorVersion, &minorVersion ); LOG( "eglInitialize gives majorVersion %i, minorVersion %i", majorVersion, minorVersion); const char * eglVendorString = eglQueryString( egl.display, EGL_VENDOR ); LOG( "EGL_VENDOR: %s", eglVendorString ); const char * eglClientApisString = eglQueryString( egl.display, EGL_CLIENT_APIS ); LOG( "EGL_CLIENT_APIS: %s", eglClientApisString ); const char * eglVersionString = eglQueryString( egl.display, EGL_VERSION ); LOG( "EGL_VERSION: %s", eglVersionString ); const char * eglExtensionString = eglQueryString( egl.display, EGL_EXTENSIONS ); LOG( "EGL_EXTENSIONS:" ); LogStringWords( eglExtensionString ); // We do NOT want to use eglChooseConfig, because the Android EGL code pushes in // multisample flags behind our back if the user has selected the "force 4x MSAA" // option in developer settings, and that is completely wasted for our warp target. egl.config = ChooseColorConfig( egl.display, redBits, greenBits, blueBits, depthBits, multisamples, true /* pBuffer compatible */ ); if ( egl.config == 0 ) { FAIL( "No acceptable EGL color configs." ); return egl; } // The EGLContext is created with the EGLConfig // Try to get an OpenGL ES 3.0 context first, which is required to do // MSAA to framebuffer objects on Adreno. for ( int version = requestedGlEsVersion ; version >= 2 ; version-- ) { LOG( "Trying for a EGL_CONTEXT_CLIENT_VERSION %i context shared with %p:", version, shareContext ); // We want the application context to be lower priority than the TimeWarp context. EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, version, EGL_NONE, EGL_NONE, EGL_NONE }; // Don't set EGL_CONTEXT_PRIORITY_LEVEL_IMG at all if set to EGL_CONTEXT_PRIORITY_MEDIUM_IMG, // It is the caller's responsibility to use that if the driver doesn't support it. if ( contextPriority != EGL_CONTEXT_PRIORITY_MEDIUM_IMG ) { contextAttribs[2] = EGL_CONTEXT_PRIORITY_LEVEL_IMG; contextAttribs[3] = contextPriority; } egl.context = eglCreateContext( egl.display, egl.config, shareContext, contextAttribs ); if ( egl.context != EGL_NO_CONTEXT ) { LOG( "Succeeded." ); egl.glEsVersion = version; EGLint configIDReadback; if ( !eglQueryContext( egl.display, egl.context, EGL_CONFIG_ID, &configIDReadback ) ) { WARN("eglQueryContext EGL_CONFIG_ID failed" ); } EGLConfig configCheck = EglConfigForConfigID( egl.display, configIDReadback ); LOG( "Created context with config %i, query returned ID %i = config %i", (int)egl.config, configIDReadback, (int)configCheck ); break; } } if ( egl.context == EGL_NO_CONTEXT ) { WARN( "eglCreateContext failed: %s", EglErrorString() ); return egl; } if ( contextPriority != EGL_CONTEXT_PRIORITY_MEDIUM_IMG ) { // See what context priority we actually got EGLint actualPriorityLevel; eglQueryContext( egl.display, egl.context, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &actualPriorityLevel ); switch ( actualPriorityLevel ) { case EGL_CONTEXT_PRIORITY_HIGH_IMG: LOG( "Context is EGL_CONTEXT_PRIORITY_HIGH_IMG" ); break; case EGL_CONTEXT_PRIORITY_MEDIUM_IMG: LOG( "Context is EGL_CONTEXT_PRIORITY_MEDIUM_IMG" ); break; case EGL_CONTEXT_PRIORITY_LOW_IMG: LOG( "Context is EGL_CONTEXT_PRIORITY_LOW_IMG" ); break; default: LOG( "Context has unknown priority level" ); break; } } // Because EGL_KHR_surfaceless_context is not widespread (Only on Tegra as of // September 2013), we need to create a tiny pbuffer surface to make the context // current. // // It is necessary to use a config with the same characteristics that the // context was created with, plus the pbuffer flag, or we will get an // EGL_BAD_MATCH error on the eglMakeCurrent() call. // // This is necessary to support 565 framebuffers, which may be important // for higher refresh rate displays. const EGLint attrib_list[] = { EGL_WIDTH, 16, EGL_HEIGHT, 16, EGL_NONE }; egl.pbufferSurface = eglCreatePbufferSurface( egl.display, egl.config, attrib_list ); if ( egl.pbufferSurface == EGL_NO_SURFACE ) { WARN( "eglCreatePbufferSurface failed: %s", EglErrorString() ); eglDestroyContext( egl.display, egl.context ); egl.context = EGL_NO_CONTEXT; return egl; } if ( eglMakeCurrent( egl.display, egl.pbufferSurface, egl.pbufferSurface, egl.context ) == EGL_FALSE ) { WARN( "eglMakeCurrent pbuffer failed: %s", EglErrorString() ); eglDestroySurface( egl.display, egl.pbufferSurface ); eglDestroyContext( egl.display, egl.context ); egl.context = EGL_NO_CONTEXT; return egl; } const char * glVendorString = (const char *) glGetString(GL_VENDOR); LOG( "GL_VENDOR: %s", glVendorString); const char * glRendererString = (const char *) glGetString(GL_RENDERER); LOG( "GL_RENDERER: %s", glRendererString); const char * glVersionString = (const char *) glGetString(GL_VERSION); LOG( "GL_VERSION: %s", glVersionString); const char * glSlVersionString = (const char *) glGetString( GL_SHADING_LANGUAGE_VERSION); LOG( "GL_SHADING_LANGUAGE_VERSION: %s", glSlVersionString); egl.gpuType = EglGetGpuType(); return egl; }
bool EGLInteropResource::ensureD3D9EGL(int w, int h) { if (surface9 && res[0].w == w && res[0].h == h) return true; #if QTAV_HAVE(GUI_PRIVATE) QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); egl->dpy = static_cast<EGLDisplay>(nativeInterface->nativeResourceForContext("eglDisplay", QOpenGLContext::currentContext())); EGLConfig egl_cfg = static_cast<EGLConfig>(nativeInterface->nativeResourceForContext("eglConfig", QOpenGLContext::currentContext())); #else #ifdef Q_OS_WIN #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) #ifdef _MSC_VER #pragma message("ANGLE version in Qt<5.5 does not support eglQueryContext. You must upgrade your runtime ANGLE libraries") #else #warning "ANGLE version in Qt<5.5 does not support eglQueryContext. You must upgrade your runtime ANGLE libraries" #endif //_MSC_VER #endif #endif //Q_OS_WIN // eglQueryContext() added (Feb 2015): https://github.com/google/angle/commit/8310797003c44005da4143774293ea69671b0e2a egl->dpy = eglGetCurrentDisplay(); qDebug("EGL version: %s, client api: %s", eglQueryString(egl->dpy, EGL_VERSION), eglQueryString(egl->dpy, EGL_CLIENT_APIS)); // TODO: check runtime egl>=1.4 for eglGetCurrentContext() EGLint cfg_id = 0; EGL_ENSURE(eglQueryContext(egl->dpy, eglGetCurrentContext(), EGL_CONFIG_ID , &cfg_id) == EGL_TRUE, false); qDebug("egl config id: %d", cfg_id); EGLint nb_cfg = 0; EGL_ENSURE(eglGetConfigs(egl->dpy, NULL, 0, &nb_cfg) == EGL_TRUE, false); qDebug("eglGetConfigs number: %d", nb_cfg); QVector<EGLConfig> cfgs(nb_cfg); //check > 0 EGL_ENSURE(eglGetConfigs(egl->dpy, cfgs.data(), cfgs.size(), &nb_cfg) == EGL_TRUE, false); EGLConfig egl_cfg = NULL; for (int i = 0; i < nb_cfg; ++i) { EGLint id = 0; eglGetConfigAttrib(egl->dpy, cfgs[i], EGL_CONFIG_ID, &id); if (id == cfg_id) { egl_cfg = cfgs[i]; break; } } #endif qDebug("egl display:%p config: %p", egl->dpy, egl_cfg); // check extensions QList<QByteArray> extensions = QByteArray(eglQueryString(egl->dpy, EGL_EXTENSIONS)).split(' '); // ANGLE_d3d_share_handle_client_buffer will be used if possible const bool kEGL_ANGLE_d3d_share_handle_client_buffer = extensions.contains("EGL_ANGLE_d3d_share_handle_client_buffer"); const bool kEGL_ANGLE_query_surface_pointer = extensions.contains("EGL_ANGLE_query_surface_pointer"); if (!kEGL_ANGLE_d3d_share_handle_client_buffer && !kEGL_ANGLE_query_surface_pointer) { qWarning("EGL extension 'kEGL_ANGLE_query_surface_pointer' or 'ANGLE_d3d_share_handle_client_buffer' is required!"); return false; } GLint has_alpha = 1; //QOpenGLContext::currentContext()->format().hasAlpha() eglGetConfigAttrib(egl->dpy, egl_cfg, EGL_BIND_TO_TEXTURE_RGBA, &has_alpha); //EGL_ALPHA_SIZE EGLint attribs[] = { EGL_WIDTH, w, EGL_HEIGHT, h, EGL_TEXTURE_FORMAT, has_alpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, EGL_NONE }; HANDLE share_handle = NULL; if (!kEGL_ANGLE_d3d_share_handle_client_buffer && kEGL_ANGLE_query_surface_pointer) { EGL_ENSURE((egl->surface = eglCreatePbufferSurface(egl->dpy, egl_cfg, attribs)) != EGL_NO_SURFACE, false); qDebug("pbuffer surface: %p", egl->surface); PFNEGLQUERYSURFACEPOINTERANGLEPROC eglQuerySurfacePointerANGLE = reinterpret_cast<PFNEGLQUERYSURFACEPOINTERANGLEPROC>(eglGetProcAddress("eglQuerySurfacePointerANGLE")); if (!eglQuerySurfacePointerANGLE) { qWarning("EGL_ANGLE_query_surface_pointer is not supported"); return false; } EGL_ENSURE(eglQuerySurfacePointerANGLE(egl->dpy, egl->surface, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, &share_handle), false); } SafeRelease(&surface9); SafeRelease(&texture9); // _A8 for a yuv plane /* * d3d resource share requires windows >= vista: https://msdn.microsoft.com/en-us/library/windows/desktop/bb219800(v=vs.85).aspx * from extension files: * d3d9: level must be 1, dimensions must match EGL surface's * d3d9ex or d3d10: */ DX_ENSURE(device9->CreateTexture(w, h, 1, D3DUSAGE_RENDERTARGET, has_alpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture9, &share_handle) , false); DX_ENSURE(texture9->GetSurfaceLevel(0, &surface9), false); if (kEGL_ANGLE_d3d_share_handle_client_buffer) { // requires extension EGL_ANGLE_d3d_share_handle_client_buffer // egl surface size must match d3d texture's // d3d9ex or d3d10 is required EGL_ENSURE((egl->surface = eglCreatePbufferFromClientBuffer(egl->dpy, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, share_handle, egl_cfg, attribs)), false); qDebug("pbuffer surface from client buffer: %p", egl->surface); } return true; }
cairo_device_t * cairo_egl_device_create (EGLDisplay dpy, EGLContext egl) { cairo_egl_context_t *ctx; cairo_status_t status; int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, }; EGLConfig config; EGLint numConfigs; ctx = calloc (1, sizeof (cairo_egl_context_t)); if (unlikely (ctx == NULL)) return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY); ctx->display = dpy; ctx->context = egl; ctx->base.acquire = _egl_acquire; ctx->base.release = _egl_release; ctx->base.make_current = _egl_make_current; ctx->base.swap_buffers = _egl_swap_buffers; ctx->base.destroy = _egl_destroy; /* We are about the change the current state of EGL, so we should * query the pre-existing surface now instead of later. */ _egl_query_current_state (ctx); if (!_egl_make_current_surfaceless (ctx)) { /* Fall back to dummy surface, meh. */ EGLint config_attribs[] = { EGL_CONFIG_ID, 0, EGL_NONE }; /* * In order to be able to make an egl context current when using a * pbuffer surface, that surface must have been created with a config * that is compatible with the context config. For Mesa, this means * that the configs must be the same. */ eglQueryContext (dpy, egl, EGL_CONFIG_ID, &config_attribs[1]); eglChooseConfig (dpy, config_attribs, &config, 1, &numConfigs); ctx->dummy_surface = eglCreatePbufferSurface (dpy, config, attribs); if (ctx->dummy_surface == NULL) { free (ctx); return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY); } if (!eglMakeCurrent (dpy, ctx->dummy_surface, ctx->dummy_surface, egl)) { free (ctx); return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY); } } status = _cairo_gl_dispatch_init (&ctx->base.dispatch, eglGetProcAddress); if (unlikely (status)) { free (ctx); return _cairo_gl_context_create_in_error (status); } status = _cairo_gl_context_init (&ctx->base); if (unlikely (status)) { if (ctx->dummy_surface != EGL_NO_SURFACE) eglDestroySurface (dpy, ctx->dummy_surface); free (ctx); return _cairo_gl_context_create_in_error (status); } eglMakeCurrent (dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); return &ctx->base.base; }
QEglContext *QVGEGLWindowSurfaceDirect::ensureContext(QWidget *widget) { QSize newSize = windowSurfaceSize(widget); QEglProperties surfaceProps; #if defined(QVG_RECREATE_ON_SIZE_CHANGE) #if !defined(QVG_NO_SINGLE_CONTEXT) if (context && size != newSize) { // The surface size has changed, so we need to recreate it. // We can keep the same context and paint engine. size = newSize; if (isPaintingActive) context->doneCurrent(); context->destroySurface(windowSurface); #if defined(EGL_VG_ALPHA_FORMAT_PRE_BIT) if (isPremultipliedContext(context)) { surfaceProps.setValue (EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE); } else { surfaceProps.removeValue(EGL_VG_ALPHA_FORMAT); } #endif windowSurface = context->createSurface(widget, &surfaceProps); isPaintingActive = false; needToSwap = true; } #else if (context && size != newSize) { // The surface size has changed, so we need to recreate // the EGL context for the widget. We also need to recreate // the surface's paint engine if context sharing is not // enabled because we cannot reuse the existing paint objects // in the new context. qt_vg_destroy_paint_engine(engine); engine = 0; context->destroySurface(windowSurface); qt_vg_destroy_context(context, QInternal::Widget); context = 0; windowSurface = EGL_NO_SURFACE; } #endif #endif if (!context) { // Create a new EGL context and bind it to the widget surface. size = newSize; context = qt_vg_create_context(widget, QInternal::Widget); if (!context) return 0; // We want a direct to window rendering surface if possible. #if defined(QVG_DIRECT_TO_WINDOW) surfaceProps.setValue(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER); #endif #if defined(EGL_VG_ALPHA_FORMAT_PRE_BIT) if (isPremultipliedContext(context)) { surfaceProps.setValue (EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE); } else { surfaceProps.removeValue(EGL_VG_ALPHA_FORMAT); } #endif EGLSurface surface = context->createSurface(widget, &surfaceProps); if (surface == EGL_NO_SURFACE) { qt_vg_destroy_context(context, QInternal::Widget); context = 0; return 0; } needToSwap = true; #if defined(QVG_DIRECT_TO_WINDOW) // Did we get a direct to window rendering surface? EGLint buffer = 0; if (eglQueryContext(QEgl::display(), context->context(), EGL_RENDER_BUFFER, &buffer) && buffer == EGL_SINGLE_BUFFER) { needToSwap = false; } #endif windowSurface = surface; isPaintingActive = false; } #if !defined(QVG_NO_PRESERVED_SWAP) // Try to force the surface back buffer to preserve its contents. if (needToSwap) { eglGetError(); // Clear error state first. eglSurfaceAttrib(QEgl::display(), windowSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); if (eglGetError() != EGL_SUCCESS) { qWarning("QVG: could not enable preserved swap"); } } #endif return context; }
int ngi_context_egl_init(ngi_context* ctx, ngi_window* win) { EGLNativeDisplayType ndpy = NULL; EGLNativeWindowType nwnd = 0; #ifdef NGI_WINDOW_XLIB if(win->app->type == ngi_wm_api_xlib ) { ndpy = (EGLNativeDisplayType)win->app->plat.xlib.dpy; nwnd = (EGLNativeWindowType)win->plat.xlib.win; } #endif ctx->type = ngi_context_api_egl; EGLDisplay edpy = ctx->platform.egl.edpy = eglGetDisplay( ndpy ); EGLint majorVersion, minorVersion; int succ; EGLConfig ecfg; EGLint num_config; EGLContext ectxt; EGLSurface esfc; EGLint ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLint attr[] = { /* EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT,*/ /* EGL_NATIVE_RENDERABLE, 1,*/ /* EGL_CONFIG_CAVEAT, EGL_NONE,*/ EGL_NONE }; printf("eglGetDisplay: %p\n", edpy); checkEGL(); succ = eglInitialize(edpy, &majorVersion, &minorVersion); printf("eglInitialize: %d\n", succ); checkEGL(); // eglBindAPI(EGL_OPENGL_API); const char* apis = eglQueryString(edpy, EGL_CLIENT_APIS); const char* exts = eglQueryString(edpy, EGL_EXTENSIONS); printf("EGL APIs: %s\n", apis); printf("EGL Extensions: %s\n", exts); if(!eglChooseConfig(edpy, attr, &ecfg, 1, &num_config)) { printf("eglChooseConfig error\n"); return 0; } if(num_config != 1) { printf("More than one config: %d\n", num_config); return 0; } checkEGL(); esfc = ctx->platform.egl.esfc = eglCreateWindowSurface(edpy, ecfg, nwnd, NULL); if(esfc == EGL_NO_SURFACE) { printf("Unable to create EGL surface (%x)\n", eglGetError()); return 0; } ectxt = ctx->platform.egl.ectx = eglCreateContext(edpy, ecfg, EGL_NO_CONTEXT, ctxattr); if(ectxt == EGL_NO_CONTEXT) { printf("Unable to create EGL context (%x)\n", eglGetError()); return 0; } eglMakeCurrent(edpy, esfc, esfc, ectxt); checkEGL(); EGLint val = 0; eglQueryContext(edpy, ectxt, EGL_CONTEXT_CLIENT_TYPE, &val); printf("Context client type: %x\n", val); eglQueryContext(edpy, ectxt, EGL_CONTEXT_CLIENT_VERSION, &val); printf("Context client version: %d\n", val); EGLenum api = eglQueryAPI(); int ver=0; switch(api) { case EGL_OPENGL_ES_API: eglQueryContext(edpy, ectxt, EGL_CONTEXT_CLIENT_VERSION, &ver); switch(ver) { case 1: ctx->graphics = ngi_graphics_api_gles1; break; case 2: ctx->graphics = ngi_graphics_api_gles2; break; default: printf("Unsupported GLES version %d\n", ver); } break; case EGL_OPENGL_API: ctx->graphics = ngi_graphics_api_opengl; break; default: printf("Unsupported EGL Graphics api 0x%x\n", api); } eglSwapInterval(edpy,1); win->context = ctx; return 1; }
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; }