Sfoglia il codice sorgente

Added EGL swap chain.

Branimir Karadžić 11 anni fa
parent
commit
7362288131
3 ha cambiato i file con 117 aggiunte e 47 eliminazioni
  1. 97 36
      src/glcontext_egl.cpp
  2. 1 0
      src/glcontext_egl.h
  3. 19 11
      src/renderer_gl.cpp

+ 97 - 36
src/glcontext_egl.cpp

@@ -35,6 +35,7 @@ namespace bgfx
 	typedef EGLSurface (EGLAPIENTRY* PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
 	typedef EGLSurface (EGLAPIENTRY* PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
 	typedef EGLBoolean (EGLAPIENTRY* PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy, const EGLint *attrib_list,	EGLConfig *configs, EGLint config_size,	EGLint *num_config);
 	typedef EGLBoolean (EGLAPIENTRY* PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy, const EGLint *attrib_list,	EGLConfig *configs, EGLint config_size,	EGLint *num_config);
 	typedef EGLBoolean (EGLAPIENTRY* PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint *major, EGLint *minor);
 	typedef EGLBoolean (EGLAPIENTRY* PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+	typedef EGLint     (EGLAPIENTRY* PFNEGLGETERRORPROC)(void);
 	typedef EGLDisplay (EGLAPIENTRY* PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id);
 	typedef EGLDisplay (EGLAPIENTRY* PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id);
 	typedef EGLBoolean (EGLAPIENTRY* PFNEGLTERMINATEPROC)(EGLDisplay dpy);
 	typedef EGLBoolean (EGLAPIENTRY* PFNEGLTERMINATEPROC)(EGLDisplay dpy);
 	typedef EGLBoolean (EGLAPIENTRY* PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface);
 	typedef EGLBoolean (EGLAPIENTRY* PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface);
@@ -49,6 +50,7 @@ namespace bgfx
 			EGL_IMPORT_FUNC(PFNEGLCREATEWINDOWSURFACEPROC, eglCreateWindowSurface); \
 			EGL_IMPORT_FUNC(PFNEGLCREATEWINDOWSURFACEPROC, eglCreateWindowSurface); \
 			EGL_IMPORT_FUNC(PFNEGLCHOOSECONFIGPROC,        eglChooseConfig); \
 			EGL_IMPORT_FUNC(PFNEGLCHOOSECONFIGPROC,        eglChooseConfig); \
 			EGL_IMPORT_FUNC(PFNEGLINITIALIZEPROC,          eglInitialize); \
 			EGL_IMPORT_FUNC(PFNEGLINITIALIZEPROC,          eglInitialize); \
+			EGL_IMPORT_FUNC(PFNEGLGETERRORPROC,            eglGetError); \
 			EGL_IMPORT_FUNC(PFNEGLGETDISPLAYPROC,          eglGetDisplay); \
 			EGL_IMPORT_FUNC(PFNEGLGETDISPLAYPROC,          eglGetDisplay); \
 			EGL_IMPORT_FUNC(PFNEGLTERMINATEPROC,           eglTerminate); \
 			EGL_IMPORT_FUNC(PFNEGLTERMINATEPROC,           eglTerminate); \
 			EGL_IMPORT_FUNC(PFNEGLDESTROYSURFACEPROC,      eglDestroySurface); \
 			EGL_IMPORT_FUNC(PFNEGLDESTROYSURFACEPROC,      eglDestroySurface); \
@@ -98,6 +100,66 @@ EGL_IMPORT
 #	define GL_IMPORT(_optional, _proto, _func, _import) _proto _func = NULL
 #	define GL_IMPORT(_optional, _proto, _func, _import) _proto _func = NULL
 #	include "glimports.h"
 #	include "glimports.h"
 
 
+	static const EGLint s_contextAttrs[] =
+	{
+#	if BGFX_CONFIG_RENDERER_OPENGLES >= 30
+		EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
+#		if BGFX_CONFIG_RENDERER_OPENGLES >= 31
+		EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+#		else
+		//			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
+#		endif // BGFX_CONFIG_RENDERER_OPENGLES >= 31
+#	elif BGFX_CONFIG_RENDERER_OPENGLES
+		EGL_CONTEXT_MAJOR_VERSION_KHR, 2,
+		//			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
+#	endif // BGFX_CONFIG_RENDERER_
+
+		EGL_NONE
+	};
+
+	struct SwapChainGL
+	{
+		SwapChainGL(EGLDisplay _display, EGLConfig _config, EGLContext _context, EGLNativeWindowType _nwh)
+			: m_nwh(_nwh)
+			, m_display(_display)
+		{
+			m_surface = eglCreateWindowSurface(m_display, _config, _nwh, NULL);
+			BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");
+
+			m_context = eglCreateContext(m_display, _config, _context, s_contextAttrs);
+			BX_CHECK(NULL != m_context, "Create swap chain failed: %x", eglGetError() );
+
+			makeCurrent();
+			GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) );
+			GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) );
+			swapBuffers();
+			GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) );
+			swapBuffers();
+		}
+
+		~SwapChainGL()
+		{
+			eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+			eglDestroyContext(m_display, m_context);
+			eglDestroySurface(m_display, m_surface);
+		}
+
+		void makeCurrent()
+		{
+			eglMakeCurrent(m_display, m_surface, m_surface, m_context);
+		}
+
+		void swapBuffers()
+		{
+			eglSwapBuffers(m_display, m_surface);
+		}
+
+		EGLNativeWindowType m_nwh;
+		EGLContext m_context;
+		EGLDisplay m_display;
+		EGLSurface m_surface;
+	};
+
 #	if BX_PLATFORM_RPI
 #	if BX_PLATFORM_RPI
 	static EGL_DISPMANX_WINDOW_T s_dispmanWindow;
 	static EGL_DISPMANX_WINDOW_T s_dispmanWindow;
 
 
@@ -118,10 +180,10 @@ EGL_IMPORT
 
 
 		BX_UNUSED(_width, _height);
 		BX_UNUSED(_width, _height);
 		EGLNativeDisplayType ndt = EGL_DEFAULT_DISPLAY;
 		EGLNativeDisplayType ndt = EGL_DEFAULT_DISPLAY;
-		EGLNativeWindowType nwt = (EGLNativeWindowType)NULL;
+		EGLNativeWindowType nwh = (EGLNativeWindowType)NULL;
 #	if BX_PLATFORM_WINDOWS
 #	if BX_PLATFORM_WINDOWS
 		ndt = GetDC(g_bgfxHwnd);
 		ndt = GetDC(g_bgfxHwnd);
-		nwt = g_bgfxHwnd;
+		nwh = g_bgfxHwnd;
 #	endif // BX_PLATFORM_
 #	endif // BX_PLATFORM_
 		m_display = eglGetDisplay(ndt);
 		m_display = eglGetDisplay(ndt);
 		BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display);
 		BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display);
@@ -146,15 +208,14 @@ EGL_IMPORT
 		};
 		};
 
 
 		EGLint numConfig = 0;
 		EGLint numConfig = 0;
-		EGLConfig config;
-		success = eglChooseConfig(m_display, attrs, &config, 1, &numConfig);
+		success = eglChooseConfig(m_display, attrs, &m_config, 1, &numConfig);
 		BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig");
 		BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig");
 
 
 #	if BX_PLATFORM_ANDROID
 #	if BX_PLATFORM_ANDROID
 		EGLint format;
 		EGLint format;
-		eglGetConfigAttrib(m_display, config, EGL_NATIVE_VISUAL_ID, &format);
+		eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format);
 		ANativeWindow_setBuffersGeometry(g_bgfxAndroidWindow, _width, _height, format);
 		ANativeWindow_setBuffersGeometry(g_bgfxAndroidWindow, _width, _height, format);
-		nwt = g_bgfxAndroidWindow;
+		nwh = g_bgfxAndroidWindow;
 #	elif BX_PLATFORM_RPI
 #	elif BX_PLATFORM_RPI
 		DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
 		DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
 		DISPMANX_UPDATE_HANDLE_T  dispmanUpdate  = vc_dispmanx_update_start(0);
 		DISPMANX_UPDATE_HANDLE_T  dispmanUpdate  = vc_dispmanx_update_start(0);
@@ -177,32 +238,15 @@ EGL_IMPORT
 		s_dispmanWindow.element = dispmanElement;
 		s_dispmanWindow.element = dispmanElement;
 		s_dispmanWindow.width   = _width;
 		s_dispmanWindow.width   = _width;
 		s_dispmanWindow.height  = _height;
 		s_dispmanWindow.height  = _height;
-		nwt = &s_dispmanWindow;
+		nwh = &s_dispmanWindow;
 
 
 		vc_dispmanx_update_submit_sync(dispmanUpdate);
 		vc_dispmanx_update_submit_sync(dispmanUpdate);
 #	endif // BX_PLATFORM_ANDROID
 #	endif // BX_PLATFORM_ANDROID
 
 
-		m_surface = eglCreateWindowSurface(m_display, config, nwt, NULL);
+		m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL);
 		BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");
 		BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");
 
 
-		EGLint contextAttrs[] =
-		{
-#	if BGFX_CONFIG_RENDERER_OPENGLES >= 30
-			EGL_CONTEXT_MAJOR_VERSION_KHR, 3,
-#		if BGFX_CONFIG_RENDERER_OPENGLES >= 31
-			EGL_CONTEXT_MINOR_VERSION_KHR, 1,
-#		else
-//			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
-#		endif // BGFX_CONFIG_RENDERER_OPENGLES >= 31
-#	elif BGFX_CONFIG_RENDERER_OPENGLES
-			EGL_CONTEXT_MAJOR_VERSION_KHR, 2,
-//			EGL_CONTEXT_MINOR_VERSION_KHR, 0,
-#	endif // BGFX_CONFIG_RENDERER_
-
-			EGL_NONE
-		};
-
-		m_context = eglCreateContext(m_display, config, EGL_NO_CONTEXT, contextAttrs);
+		m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, s_contextAttrs);
 		BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::UnableToInitialize, "Failed to create context.");
 		BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::UnableToInitialize, "Failed to create context.");
 
 
 		success = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
 		success = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
@@ -239,29 +283,46 @@ EGL_IMPORT
 
 
 	bool GlContext::isSwapChainSupported()
 	bool GlContext::isSwapChainSupported()
 	{
 	{
-		return false;
+		return BX_ENABLED(0
+						| BX_PLATFORM_LINUX
+						| BX_PLATFORM_WINDOWS
+						);
 	}
 	}
 
 
-	SwapChainGL* GlContext::createSwapChain(void* /*_nwh*/)
+	SwapChainGL* GlContext::createSwapChain(void* _nwh)
 	{
 	{
-		BX_CHECK(false, "Shouldn't be called!");
-		return NULL;
+		return BX_NEW(g_allocator, SwapChainGL)(m_display, m_config, m_context, (EGLNativeWindowType)_nwh);
 	}
 	}
 
 
-	void GlContext::destorySwapChain(SwapChainGL*  /*_swapChain*/)
+	void GlContext::destorySwapChain(SwapChainGL* _swapChain)
 	{
 	{
-		BX_CHECK(false, "Shouldn't be called!");
+		BX_DELETE(g_allocator, _swapChain);
 	}
 	}
 
 
 	void GlContext::swap(SwapChainGL* _swapChain)
 	void GlContext::swap(SwapChainGL* _swapChain)
 	{
 	{
-		BX_CHECK(NULL == _swapChain, "Shouldn't be called!"); BX_UNUSED(_swapChain);
-		eglMakeCurrent(m_display, m_surface, m_surface, m_context);
-		eglSwapBuffers(m_display, m_surface);
+		if (NULL == _swapChain)
+		{
+			eglMakeCurrent(m_display, m_surface, m_surface, m_context);
+			eglSwapBuffers(m_display, m_surface);
+		}
+		else
+		{
+			_swapChain->makeCurrent();
+			_swapChain->swapBuffers();
+		}
 	}
 	}
 
 
-	void GlContext::makeCurrent(SwapChainGL* /*_swapChain*/)
+	void GlContext::makeCurrent(SwapChainGL* _swapChain)
 	{
 	{
+		if (NULL == _swapChain)
+		{
+			eglMakeCurrent(m_display, m_surface, m_surface, m_context);
+		}
+		else
+		{
+			_swapChain->makeCurrent();
+		}
 	}
 	}
 
 
 	void GlContext::import()
 	void GlContext::import()

+ 1 - 0
src/glcontext_egl.h

@@ -41,6 +41,7 @@ namespace bgfx
 		}
 		}
 
 
 		void* m_eglLibrary;
 		void* m_eglLibrary;
+		EGLConfig  m_config;
 		EGLContext m_context;
 		EGLContext m_context;
 		EGLDisplay m_display;
 		EGLDisplay m_display;
 		EGLSurface m_surface;
 		EGLSurface m_surface;

+ 19 - 11
src/renderer_gl.cpp

@@ -1187,8 +1187,6 @@ namespace bgfx
 				|| s_extension[Extension::OES_vertex_array_object].m_supported
 				|| s_extension[Extension::OES_vertex_array_object].m_supported
 				;
 				;
 
 
-m_vaoSupport &= false;
-
 			if (BX_ENABLED(BX_PLATFORM_NACL) )
 			if (BX_ENABLED(BX_PLATFORM_NACL) )
 			{
 			{
 				m_vaoSupport &= NULL != glGenVertexArrays
 				m_vaoSupport &= NULL != glGenVertexArrays
@@ -1700,6 +1698,7 @@ m_vaoSupport &= false;
 			else
 			else
 			{
 			{
 				FrameBufferGL& frameBuffer = m_frameBuffers[_fbh.idx];
 				FrameBufferGL& frameBuffer = m_frameBuffers[_fbh.idx];
+				_height = frameBuffer.m_height;
 				if (UINT16_MAX != frameBuffer.m_denseIdx)
 				if (UINT16_MAX != frameBuffer.m_denseIdx)
 				{
 				{
 					m_glctx.makeCurrent(frameBuffer.m_swapChain);
 					m_glctx.makeCurrent(frameBuffer.m_swapChain);
@@ -1709,7 +1708,6 @@ m_vaoSupport &= false;
 				{
 				{
 					m_glctx.makeCurrent(NULL);
 					m_glctx.makeCurrent(NULL);
 					GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) );
 					GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) );
-					_height = frameBuffer.m_height;
 				}
 				}
 			}
 			}
 
 
@@ -1802,7 +1800,7 @@ m_vaoSupport &= false;
 
 
 		void setRenderContextSize(uint32_t _width, uint32_t _height, uint32_t _msaa = 0, bool _vsync = false)
 		void setRenderContextSize(uint32_t _width, uint32_t _height, uint32_t _msaa = 0, bool _vsync = false)
 		{
 		{
-			if (_width != 0
+			if (_width  != 0
 			||  _height != 0)
 			||  _height != 0)
 			{
 			{
 				if (!m_glctx.isValid() )
 				if (!m_glctx.isValid() )
@@ -3923,15 +3921,25 @@ m_vaoSupport &= false;
 
 
 	void RendererContextGL::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
 	void RendererContextGL::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)
 	{
 	{
+		if (1 < m_numWindows
+		&&  m_vaoSupport)
+		{
+			m_vaoSupport = false;
+			GL_CHECK(glBindVertexArray(0) );
+			GL_CHECK(glDeleteVertexArrays(1, &m_vao) );
+			m_vao = 0;
+			m_vaoStateCache.invalidate();
+		}
+
 		m_glctx.makeCurrent(NULL);
 		m_glctx.makeCurrent(NULL);
 
 
-		const GLuint defaultVao = s_renderGL->m_vao;
+		const GLuint defaultVao = m_vao;
 		if (0 != defaultVao)
 		if (0 != defaultVao)
 		{
 		{
 			GL_CHECK(glBindVertexArray(defaultVao) );
 			GL_CHECK(glBindVertexArray(defaultVao) );
 		}
 		}
 
 
-		GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, s_renderGL->m_backBufferFbo) );
+		GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_backBufferFbo) );
 
 
 		updateResolution(_render->m_resolution);
 		updateResolution(_render->m_resolution);
 
 
@@ -3941,19 +3949,19 @@ m_vaoSupport &= false;
 		if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
 		if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL)
 		&& (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) )
 		&& (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) )
 		{
 		{
-			s_renderGL->m_queries.begin(0, GL_TIME_ELAPSED);
+			m_queries.begin(0, GL_TIME_ELAPSED);
 		}
 		}
 
 
 		if (0 < _render->m_iboffset)
 		if (0 < _render->m_iboffset)
 		{
 		{
 			TransientIndexBuffer* ib = _render->m_transientIb;
 			TransientIndexBuffer* ib = _render->m_transientIb;
-			s_renderGL->m_indexBuffers[ib->handle.idx].update(0, _render->m_iboffset, ib->data);
+			m_indexBuffers[ib->handle.idx].update(0, _render->m_iboffset, ib->data);
 		}
 		}
 
 
 		if (0 < _render->m_vboffset)
 		if (0 < _render->m_vboffset)
 		{
 		{
 			TransientVertexBuffer* vb = _render->m_transientVb;
 			TransientVertexBuffer* vb = _render->m_transientVb;
-			s_renderGL->m_vertexBuffers[vb->handle.idx].update(0, _render->m_vboffset, vb->data);
+			m_vertexBuffers[vb->handle.idx].update(0, _render->m_vboffset, vb->data);
 		}
 		}
 
 
 		_render->sort();
 		_render->sort();
@@ -4006,7 +4014,7 @@ m_vaoSupport &= false;
 
 
 		if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
 		if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
 		{
 		{
-			GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, s_renderGL->m_msaaBackBufferFbo) );
+			GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
 
 
 			for (uint32_t item = 0, numItems = _render->m_num; item < numItems; ++item)
 			for (uint32_t item = 0, numItems = _render->m_num; item < numItems; ++item)
 			{
 			{
@@ -4025,7 +4033,7 @@ m_vaoSupport &= false;
 					if (_render->m_fb[view].idx != fbh.idx)
 					if (_render->m_fb[view].idx != fbh.idx)
 					{
 					{
 						fbh = _render->m_fb[view];
 						fbh = _render->m_fb[view];
-						height = s_renderGL->setFrameBuffer(fbh, _render->m_resolution.m_height);
+						height = setFrameBuffer(fbh, _render->m_resolution.m_height);
 					}
 					}
 
 
 					const Rect& rect = _render->m_rect[view];
 					const Rect& rect = _render->m_rect[view];