Beispiel #1
0
/*****************************************************************************
* 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;
}