/***************************************************************************** * Function Name : InitAPI * Returns : true for success * Description : Initialise the 3D API *****************************************************************************/ bool PVRShellInit::ApiInitAPI() { int bDone; #if defined(BUILD_OGLES2) || defined(BUILD_OVG) EGLNativeDisplayType ndt; #else NativeDisplayType ndt; #endif gEglContext = 0; do { bDone = true; #if defined(BUILD_OGLES2) || defined(BUILD_OVG) ndt = (EGLNativeDisplayType)OsGetNativeDisplayType(); #else ndt = (NativeDisplayType)OsGetNativeDisplayType(); #endif gEglDisplay = eglGetDisplay(ndt); if(gEglDisplay == EGL_NO_DISPLAY) { #if defined(BUILD_OGLES2) || defined(BUILD_OVG) gEglDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY); #else gEglDisplay = eglGetDisplay((NativeDisplayType)EGL_DEFAULT_DISPLAY); #endif } if(!eglInitialize(gEglDisplay, &majorVersion, &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", majorVersion, minorVersion); // Check Extension avaliablility after EGL initialization if (majorVersion > 1 || (majorVersion == 1 && minorVersion >= 1)) { powerManagementSupported = true; } else { powerManagementSupported = PVRShellIsExtensionSupported(gEglDisplay,"EGL_IMG_power_management"); } PVRShellData ShellDataBackUp; memcpy((void*) &ShellDataBackUp, m_pShell->m_pShellData, sizeof(PVRShellData)); 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"); // Find an EGL config gEglConfig = SelectEGLConfiguration(m_pShell->m_pShellData); #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 gEglConfig = SelectEGLConfiguration(m_pShell->m_pShellData); } // Destroy the context if we already created one if (gEglContext) { eglDestroyContext(gEglDisplay, gEglContext); } // Attempt to create a context #if defined BUILD_OVG gEglContext = eglCreateContext(gEglDisplay, gEglConfig, NULL, NULL); #elif defined EGL_VERSION_1_3 && defined GL_ES_VERSION_2_0 EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; gEglContext = eglCreateContext(gEglDisplay, gEglConfig, NULL, ai32ContextAttribs); #else gEglContext = eglCreateContext(gEglDisplay, gEglConfig, NULL, NULL); #endif if(gEglContext == EGL_NO_CONTEXT) { 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 if(!m_pShell->m_pShellData->bSoftwareRender) { // Still failing, reset everything and try using a software renderer memcpy(m_pShell->m_pShellData, (void*) &ShellDataBackUp, sizeof(PVRShellData)); m_pShell->m_pShellData->bSoftwareRender = true; } else { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create a context\n"); return false; } } } while(gEglContext == EGL_NO_CONTEXT); if(m_pShell->m_pShellData->bSoftwareRender) { m_pShell->PVRShellOutputDebug("PVRShell: Warning! Using the SOFTWARE renderer\n"); } 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) { #if defined(BUILD_OGLES2) || defined(BUILD_OVG) EGLNativePixmapType npt = (EGLNativePixmapType)OsGetNativePixmapType(); #else NativePixmapType npt = (NativePixmapType)OsGetNativePixmapType(); #endif m_pShell->PVRShellOutputDebug("InitAPI() Using pixmaps, about to create egl surface\n"); gEglWindow = eglCreatePixmapSurface(gEglDisplay, gEglConfig, npt, attrib_list); } else { #if defined(BUILD_OGLES2) || defined(BUILD_OVG) EGLNativeWindowType nwt = (EGLNativeWindowType)OsGetNativeWindowType(); #else NativeWindowType nwt = (NativeWindowType)OsGetNativeWindowType(); #endif gEglWindow = eglCreateWindowSurface(gEglDisplay, gEglConfig, nwt, attrib_list); // If we have failed to create a surface then try using Null if(gEglWindow == EGL_NO_SURFACE) { gEglWindow = eglCreateWindowSurface(gEglDisplay, gEglConfig, NULL, attrib_list); } } if (gEglWindow == EGL_NO_SURFACE) { m_pShell->PVRShellSet(prefExitMessage, "PVRShell: Unable to create surface\n"); return false; } if (!eglMakeCurrent(gEglDisplay, gEglWindow, gEglWindow, gEglContext)) { #ifdef EGL_VERSION_1_3 if((eglGetError() == EGL_CONTEXT_LOST)) #else if((eglGetError() == EGL_CONTEXT_LOST_IMG) && powerManagementSupported) #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(gEglDisplay, gEglWindow, EGL_WIDTH, (EGLint*)&m_pShell->m_pShellData->nShellDimX ); eglQuerySurface(gEglDisplay, gEglWindow, EGL_HEIGHT, (EGLint*)&m_pShell->m_pShellData->nShellDimY ); /* Done - activate requested features */ ApiActivatePreferences(); return true; }
/***************************************************************************** * 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; }