/** * @eglsymbols * @eglfunref{QueryContext} */ bool Query(ContextAttrib attrib, EGLint& value) const { EGLBoolean result = EGLPLUS_EGLFUNC(QueryContext)( GetEGLHandle(_display), _handle, EGLint(EGLenum(attrib)), &value ); EGLPLUS_CHECK_SIMPLE(QueryContext); return result == EGL_TRUE; }
/** * @eglsymbols * @eglfunref{GetConfigAttrib} */ EGLint GetAttrib(ConfigAttrib attrib) const { EGLint result = 0; EGLPLUS_EGLFUNC(GetConfigAttrib)( FriendOf<Display>::GetHandle(_display), this->_handle, EGLint(EGLenum(attrib)), &result ); EGLPLUS_VERIFY(EGLPLUS_ERROR_INFO(GetConfigAttrib)); return result; }
/** * @eglsymbols * @eglfunref{QueryContext} */ EGLint ConfigId(void) const { EGLint result = 0; EGLPLUS_EGLFUNC(QueryContext)( GetEGLHandle(_display), _handle, EGLint(EGL_CONFIG_ID), &result ); EGLPLUS_CHECK_SIMPLE(QueryContext); return result; }
//------------------------------------------------------------------------------ // eglGetConfigs //------------------------------------------------------------------------------ EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs( EGLDisplay display, EGLConfig * configs, EGLint config_size, EGLint * num_configs ) { if(!eglplus_egl_valid_display(display)) { eglplus_egl_SetErrorCode(EGL_BAD_DISPLAY); return EGL_FALSE; } if(!display->initialized()) { eglplus_egl_SetErrorCode(EGL_NOT_INITIALIZED); return EGL_FALSE; } if(!num_configs) { eglplus_egl_SetErrorCode(EGL_BAD_PARAMETER); return EGL_FALSE; } int num_glx_configs = 0; ::GLXFBConfig * glx_configs = ::glXGetFBConfigs( display->_x_open_display, DefaultScreen(display->_x_open_display), &num_glx_configs ); if(configs) { int n = (num_glx_configs < int(config_size))? num_glx_configs: int(config_size); for(int i=0; i<n; ++i) { configs[i]._glx_fb_config = static_cast<void*>(glx_configs[i]); } *num_configs = n>=0?n:0; } else *num_configs = EGLint(num_glx_configs); return EGL_TRUE; }
bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes) { int i = -1; // Reduce the complexity of a configuration request to ask for less // because the previous request did not result in success. Returns // true if the complexity was reduced, or false if no further // reductions in complexity are possible. i = configAttributes->indexOf(EGL_SWAP_BEHAVIOR); if (i >= 0) { configAttributes->remove(i,2); } #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT // For OpenVG, we sometimes try to create a surface using a pre-multiplied format. If we can't // find a config which supports pre-multiplied formats, remove the flag on the surface type: i = configAttributes->indexOf(EGL_SURFACE_TYPE); if (i >= 0) { EGLint surfaceType = configAttributes->at(i +1); if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) { surfaceType ^= EGL_VG_ALPHA_FORMAT_PRE_BIT; configAttributes->replace(i+1,surfaceType); return true; } } #endif // EGL chooses configs with the highest color depth over // those with smaller (but faster) lower color depths. One // way around this is to set EGL_BUFFER_SIZE to 16, which // trumps the others. Of course, there may not be a 16-bit // config available, so it's the first restraint we remove. i = configAttributes->indexOf(EGL_BUFFER_SIZE); if (i >= 0) { if (configAttributes->at(i+1) == 16) { configAttributes->remove(i,2); return true; } } i = configAttributes->indexOf(EGL_SAMPLES); if (i >= 0) { EGLint value = configAttributes->value(i+1, 0); if (value > 1) configAttributes->replace(i+1, qMin(EGLint(16), value / 2)); else configAttributes->remove(i, 2); return true; } i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS); if (i >= 0) { configAttributes->remove(i,2); return true; } i = configAttributes->indexOf(EGL_ALPHA_SIZE); if (i >= 0) { configAttributes->remove(i,2); #if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB) i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGBA); if (i >= 0) { configAttributes->replace(i,EGL_BIND_TO_TEXTURE_RGB); configAttributes->replace(i+1,true); } #endif return true; } i = configAttributes->indexOf(EGL_STENCIL_SIZE); if (i >= 0) { if (configAttributes->at(i + 1) > 1) configAttributes->replace(i + 1, 1); else configAttributes->remove(i, 2); return true; } i = configAttributes->indexOf(EGL_DEPTH_SIZE); if (i >= 0) { if (configAttributes->at(i + 1) > 1) configAttributes->replace(i + 1, 1); else configAttributes->remove(i, 2); return true; } #ifdef EGL_BIND_TO_TEXTURE_RGB i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGB); if (i >= 0) { configAttributes->remove(i,2); return true; } #endif return false; }
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"); const uint32_t gles = BGFX_CONFIG_RENDERER_OPENGLES; 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(gles / 10) ); bx::write(&writer, EGLint(EGL_CONTEXT_MINOR_VERSION_KHR) ); bx::write(&writer, EGLint(gles % 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(); g_internalData.context = m_context; }
EGLint SurfaceVk::getSwapBehavior() const { UNIMPLEMENTED(); return EGLint(); }
EGLint SurfaceVk::isPostSubBufferSupported() const { UNIMPLEMENTED(); return EGLint(); }
EGLint SurfaceVk::getHeight() const { UNIMPLEMENTED(); return EGLint(); }
EGLint SurfaceVk::getWidth() const { UNIMPLEMENTED(); return EGLint(); }
//------------------------------------------------------------------------------ // eglChooseConfig //------------------------------------------------------------------------------ EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig( EGLDisplay display, const EGLint *egl_attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_configs ) { if(!eglplus_egl_valid_display(display)) { eglplus_egl_SetErrorCode(EGL_BAD_DISPLAY); return EGL_FALSE; } if(!display->initialized()) { eglplus_egl_SetErrorCode(EGL_NOT_INITIALIZED); return EGL_FALSE; } EGLint empty_list = EGL_NONE; if(!egl_attrib_list) { egl_attrib_list = &empty_list; } std::vector<int> glx_attrib_list(1); bool unsupported_config = false; if(*egl_attrib_list != EGL_NONE) { unsigned attr_count = 0; const EGLint *egl_attrib = egl_attrib_list; while(*egl_attrib != EGL_NONE) { switch(*(++egl_attrib)) { case EGL_NONE: { eglplus_egl_SetErrorCode(EGL_BAD_ATTRIBUTE); return EGL_FALSE; } case EGL_SURFACE_TYPE: case EGL_COLOR_BUFFER_TYPE: { attr_count += 2; break; } default: ++attr_count; } ++egl_attrib; } glx_attrib_list.resize(2*attr_count+1); attr_count = 0; egl_attrib = egl_attrib_list; while(*egl_attrib != EGL_NONE) { EGLint egl_attrib_name = *(egl_attrib++); EGLint egl_attrib_value= *(egl_attrib++); int glx_attrib_name, glx_attrib_value; bool special_attrib = true; bool unsupported_attrib = false; switch(egl_attrib_name) { case EGL_MIN_SWAP_INTERVAL: case EGL_MAX_SWAP_INTERVAL: { // just skip this break; } case EGL_SAMPLES: case EGL_SAMPLE_BUFFERS: case EGL_ALPHA_MASK_SIZE: case EGL_LUMINANCE_SIZE: { // must be zero (or don't care) if(egl_attrib_value != 0) unsupported_attrib = true; break; } case EGL_RENDERABLE_TYPE: { if(egl_attrib_value != EGL_OPENGL_BIT) unsupported_attrib = true; break; } case EGL_SURFACE_TYPE: { bool doublebuffer = (egl_attrib_value & EGL_WINDOW_BIT)|| (egl_attrib_value & EGL_PBUFFER_BIT); glx_attrib_list[attr_count++] = GLX_DOUBLEBUFFER; glx_attrib_list[attr_count++] = doublebuffer?True:False; break; } case EGL_COLOR_BUFFER_TYPE: { if(egl_attrib_value == EGL_RGB_BUFFER) { glx_attrib_list[attr_count++] = GLX_RENDER_TYPE; glx_attrib_list[attr_count++] = GLX_RGBA_BIT; glx_attrib_list[attr_count++] = GLX_X_VISUAL_TYPE; glx_attrib_list[attr_count++] = GLX_TRUE_COLOR; } else unsupported_attrib = true; break; } default: special_attrib = false; } if(special_attrib) { if(unsupported_attrib) { if(egl_attrib_value != EGL_DONT_CARE) { unsupported_config = true; break; } } } else if(eglplus_egl_glx_TranslateAttrib( egl_attrib_name, egl_attrib_value, glx_attrib_name, glx_attrib_value )) { glx_attrib_list[attr_count++] = glx_attrib_name; glx_attrib_list[attr_count++] = glx_attrib_value; } else { eglplus_egl_SetErrorCode(EGL_BAD_ATTRIBUTE); return EGL_FALSE; } } glx_attrib_list.resize(2*attr_count+1); } glx_attrib_list.back() = None; if(unsupported_config) { *num_configs = 0; return EGL_TRUE; } int num_glx_configs = 0; ::GLXFBConfig * glx_configs = ::glXChooseFBConfig( display->_x_open_display, DefaultScreen(display->_x_open_display), glx_attrib_list.data(), &num_glx_configs ); if(configs) { int n = (num_glx_configs < int(config_size))? num_glx_configs: int(config_size); for(int i=0; i<n; ++i) { configs[i]._glx_fb_config = static_cast<void*>(glx_configs[i]); } *num_configs = n>=0?n:0; } else *num_configs = EGLint(num_glx_configs); return EGL_TRUE; }
//------------------------------------------------------------------------------ void eglplus_egl_glx_TranslateAttribBack( EGLint egl_attrib_name, EGLint& egl_attrib_value, int glx_attrib_value ) { switch(egl_attrib_name) { case EGL_SURFACE_TYPE: { egl_attrib_value = 0; if((glx_attrib_value & GLX_WINDOW_BIT) == GLX_WINDOW_BIT) egl_attrib_value |= EGL_WINDOW_BIT; if((glx_attrib_value & GLX_PIXMAP_BIT) == GLX_PIXMAP_BIT) egl_attrib_value |= EGL_PIXMAP_BIT; if((glx_attrib_value & GLX_PBUFFER_BIT) == GLX_PBUFFER_BIT) egl_attrib_value |= EGL_PBUFFER_BIT; break; } case EGL_NATIVE_RENDERABLE: { if(glx_attrib_value == True) egl_attrib_value = EGL_TRUE; else egl_attrib_value = EGL_FALSE; break; } case EGL_CONFIG_CAVEAT: { switch(glx_attrib_value) { case GLX_NONE: egl_attrib_value = EGL_NONE; break; case GLX_SLOW_CONFIG: egl_attrib_value = EGL_SLOW_CONFIG; break; case GLX_NON_CONFORMANT_CONFIG: egl_attrib_value = EGL_NON_CONFORMANT_CONFIG; break; } break; } case EGL_TRANSPARENT_TYPE: { switch(glx_attrib_value) { case GLX_TRANSPARENT_INDEX: case GLX_NONE: egl_attrib_value = EGL_NONE; break; case GLX_TRANSPARENT_RGB: egl_attrib_value = EGL_TRANSPARENT_RGB; break; } break; } default: egl_attrib_value = EGLint(glx_attrib_value); } }