Bladeren bron

Merge pull request #21 from computerquip/master

Various Changes to OpenGL intialization
Jim 11 jaren geleden
bovenliggende
commit
a89a8151d5
5 gewijzigde bestanden met toevoegingen van 137 en 105 verwijderingen
  1. 1 1
      configure.ac
  2. 0 26
      libobs-opengl/gl-cocoa.m
  3. 107 9
      libobs-opengl/gl-subsystem.c
  4. 3 48
      libobs-opengl/gl-windows.c
  5. 26 21
      libobs-opengl/gl-x11.c

+ 1 - 1
configure.ac

@@ -91,7 +91,7 @@ WX_CONFIG_CHECK(
 		is in LD_LIBRARY_PATH or equivalent variable and
 		wxWidgets version is $wxVersion or above.
 		]) ],
-	[core], )
+	[core], [--version=2.9])
 
 CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS"
 CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY"

+ 0 - 26
libobs-opengl/gl-cocoa.m

@@ -97,11 +97,6 @@ static NSOpenGLContext *gl_context_create(struct gs_init_data *info)
 	return context;
 }
 
-static inline void required_extension_error(const char *extension)
-{
-	blog(LOG_ERROR, "OpenGL extension %s is required", extension);
-}
-
 static bool gl_init_extensions(device_t device)
 {
 	glewExperimental=true;
@@ -112,27 +107,6 @@ static bool gl_init_extensions(device_t device)
 	       return false;
 	}
 
-	if(!GLEW_VERSION_2_1) {
-	       blog(LOG_ERROR, "OpenGL 2.1 minimum required by the graphics "
-	                       "adapter");
-	       return false;
-	}
-
-	if(!GLEW_ARB_framebuffer_object) {
-		required_extension_error("GL_ARB_framebuffer_object");
-		return false;
-	}
-
-	if(!GLEW_ARB_separate_shader_objects) {
-		required_extension_error("GL_ARB_separate_shader_objects");
-		return false;
-	}
-
-	//something inside glew produces error code 1280 (invalid enum)
-	glGetError();
-
-	device->copy_type = COPY_TYPE_FBO_BLIT;
-
 	return true;
 }
 

+ 107 - 9
libobs-opengl/gl-subsystem.c

@@ -18,6 +18,107 @@
 #include <graphics/matrix3.h>
 #include "gl-subsystem.h"
 
+#ifdef _DEBUG
+/* Tables for OpenGL debug */
+static const char* debug_source_table[] = {
+	"API",
+	"Window System",
+	"Shader Compiler",
+	"Third Party"
+	"Application",
+	"Other"
+};
+
+static const char* debug_type_table[] = {
+	"Error",
+	"Deprecated Behavior",
+	"Undefined Behavior",
+	"Portability",
+	"Performance",
+	"Other"
+};
+
+static const char* debug_severity_table[] = {
+	"High",
+	"Medium",
+	"Low"
+};
+
+/* ARB and core values are the same. They'll always be linear so no hardcoding. */
+/* The values subtracted are the lowest value in the list of valid values. */
+#define GL_DEBUG_SOURCE_OFFSET(x) (x - GL_DEBUG_SOURCE_API_ARB)
+#define GL_DEBUG_TYPE_OFFSET(x) (x - GL_DEBUG_TYPE_ERROR_ARB)
+#define GL_DEBUG_SEVERITY_OFFSET(x) (x - GL_DEBUG_SEVERITY_HIGH_ARB)
+
+static APIENTRY void gl_debug_proc(
+	GLenum source, GLenum type, GLuint id, GLenum severity, 
+	GLsizei length, const GLchar *message, GLvoid *data )
+{
+	blog(	LOG_DEBUG,
+		"[%s][%s]{%s}: %.*s",
+		debug_source_table[GL_DEBUG_SOURCE_OFFSET(source)],
+		debug_type_table[GL_DEBUG_TYPE_OFFSET(type)],
+		debug_severity_table[GL_DEBUG_SEVERITY_OFFSET(severity)],
+		length, message
+	);
+}
+
+static void gl_enable_debug()
+{
+	 /* Perhaps we should create GLEW contexts? */
+
+	if (GLEW_VERSION_4_0)
+		glDebugMessageCallback(gl_debug_proc, NULL);
+	else if (GLEW_ARB_debug_output) 
+		glDebugMessageCallbackARB(gl_debug_proc, NULL);
+	else {
+		blog(LOG_DEBUG, "Failed to set GL debug callback as it is not supported.");
+		return;
+	}
+
+	gl_enable(GL_DEBUG_OUTPUT);
+}
+#else
+static void gl_enable_debug() {}
+#endif
+
+static inline void required_extension_error(const char *extension)
+{
+}
+
+static bool gl_init_extensions(struct gs_device* device) 
+{
+	if (!GLEW_VERSION_2_1) {
+		blog(LOG_ERROR, "obs-studio requires OpenGL version 2.1 or higher.");
+		return false;
+	}
+
+	gl_enable_debug();
+
+	if (!GLEW_VERSION_3_0 && !GLEW_ARB_framebuffer_object) {
+		blog(LOG_ERROR, "OpenGL extension ARB_framebuffer_object is required.");
+		return false;
+	}
+
+	if (GLEW_VERSION_3_1 || GLEW_ARB_seamless_cube_map) {
+		gl_enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+	}
+
+	if (!GLEW_VERSION_4_1 && !GLEW_ARB_separate_shader_objects) {
+		blog(LOG_ERROR, "OpenGL extension ARB_separate_shader_objects is required.");
+		return false;
+	}
+
+	if (GLEW_ARB_copy_image || GLEW_VERSION_4_2)
+		device->copy_type = COPY_TYPE_ARB;
+	else if (GLEW_NV_copy_image)
+		device->copy_type = COPY_TYPE_NV;
+	else
+		device->copy_type = COPY_TYPE_FBO_BLIT; /* ?? */
+
+	return true;
+}
+
 static void clear_textures(struct gs_device *device)
 {
 	GLenum i;
@@ -69,6 +170,11 @@ device_t device_create(struct gs_init_data *info)
 	if (!device->plat)
 		goto fail;
 
+	if (!gl_init_extensions(device))
+		goto fail;
+	
+	gl_enable(GL_CULL_FACE);
+	
 	glGenProgramPipelines(1, &device->pipeline);
 	if (!gl_success("glGenProgramPipelines"))
 		goto fail;
@@ -77,14 +183,6 @@ device_t device_create(struct gs_init_data *info)
 	if (!gl_success("glBindProgramPipeline"))
 		goto fail;
 
-#ifdef _DEBUG
-	glEnable(GL_DEBUG_OUTPUT);
-	if (glGetError() == GL_INVALID_ENUM)
-		blog(LOG_DEBUG, "OpenGL debug information not available");
-#endif
-
-	gl_enable(GL_CULL_FACE);
-
 	device_leavecontext(device);
 	device->cur_swap = gl_platform_getswap(device->plat);
 
@@ -1045,7 +1143,7 @@ void device_frustum(device_t device, float left, float right,
 
 	dst->x.x =            nearx2 / rml;
 	dst->z.x =      (left+right) / rml;
-                       
+					   
 	dst->y.y =            nearx2 / tmb;
 	dst->z.y =      (bottom+top) / tmb;
 

+ 3 - 48
libobs-opengl/gl-windows.c

@@ -155,10 +155,9 @@ static inline HGLRC gl_init_basic_context(HDC hdc)
 
 static const int attribs[] = 
 {
-	WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
-	WGL_CONTEXT_MINOR_VERSION_ARB, 2,
-	WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB |
-	                       WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+#ifdef _DEBUG
+    WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
+#endif
 	WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
 	0, 0
 };
@@ -244,29 +243,11 @@ static bool gl_init_extensions(device_t device)
 		return false;
 	}
 
-	if (!GLEW_VERSION_2_1) {
-		blog(LOG_ERROR, "OpenGL 2.1 minimum required by the graphics "
-		                "adapter");
-		return false;
-	}
-
-	if (!GLEW_ARB_framebuffer_object) {
-		required_extension_error("GL_ARB_framebuffer_object");
-		return false;
-	}
-
 	if (!WGLEW_ARB_pixel_format) {
 		required_extension_error("WGL_ARB_pixel_format");
 		return false;
 	}
 
-	if (GLEW_ARB_copy_image)
-		device->copy_type = COPY_TYPE_ARB;
-	else if (GLEW_NV_copy_image)
-		device->copy_type = COPY_TYPE_NV;
-	else
-		device->copy_type = COPY_TYPE_FBO_BLIT;
-
 	return true;
 }
 
@@ -377,19 +358,6 @@ static bool init_default_swap(struct gl_platform *plat, device_t device,
 	return true;
 }
 
-#ifdef _DEBUG
-static void APIENTRY gl_debug_message_amd(GLuint id,
-                                          GLenum category,
-                                          GLenum severity,
-                                          GLsizei length,
-                                          const GLchar *msg,
-                                          void *param)
-{
-	OutputDebugStringA(msg);
-	OutputDebugStringA("\n");
-}
-#endif
-
 void gl_update(device_t device)
 {
 	/* does nothing on windows */
@@ -425,19 +393,6 @@ struct gl_platform *gl_platform_create(device_t device,
 	if (!plat->hrc)
 		goto fail;
 
-	if (GLEW_ARB_seamless_cube_map) {
-		glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
-		gl_success("GL_TEXTURE_CUBE_MAP_SEAMLESS");
-	}
-
-#ifdef _DEBUG
-	if (GLEW_AMD_debug_output) {
-		glDebugMessageEnableAMD(0, 0, 0, NULL, true);
-		glDebugMessageCallbackAMD(gl_debug_message_amd, device);
-		gl_success("glDebugMessageCallback");
-	}
-#endif
-
 	return plat;
 
 fail:

+ 26 - 21
libobs-opengl/gl-x11.c

@@ -19,12 +19,11 @@ static const GLenum fb_attribs[] = {
 };
 
 static const GLenum ctx_attribs[] = {
-	GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
-	GLX_CONTEXT_MINOR_VERSION_ARB, 2,
-	GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB |
-	                       GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+#ifdef _DEBUG
+	GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
+#endif
 	GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
-	0, 0
+	None, 
 };
 
 static const char* __GLX_error_table[] = {
@@ -106,24 +105,14 @@ static void print_info_stuff(struct gs_init_data *info)
 struct gl_platform *gl_platform_create(device_t device,
 		struct gs_init_data *info)
 {	
-	/* X11 */
 	int num_configs = 0;
 	int error_base = 0, event_base = 0;
 	Display *display = XOpenDisplay(NULL); /* Open default screen */
-	
-	/* OBS */
 	struct gl_platform *plat = bmalloc(sizeof(struct gl_platform));
-	
-	/* GLX */
 	GLXFBConfig* configs;
 	
 	print_info_stuff(info);
 	
-	if (!plat) { 
-		blog(LOG_ERROR, "Out of memory");
-		return NULL;
-	}
-	
 	memset(plat, 0, sizeof(struct gl_platform));
 	
 	if (!display) {
@@ -139,6 +128,17 @@ struct gl_platform *gl_platform_create(device_t device,
 	
 	XSetErrorHandler(GLXErrorHandler);
 	
+	/* We require glX version 1.4 */
+	{
+		int major = 0, minor = 0;
+		
+		glXQueryVersion(display, &major, &minor);
+		if (major < 1 || minor < 4) {
+			blog(LOG_ERROR, "GLX version found: %i.%i\nRequired: 1.4", major, minor);
+			goto fail0;
+		}
+	}
+	
 	glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress("glXCreateContextAttribsARB");
 	if (!glXCreateContextAttribsARB) {
 		blog(LOG_ERROR, "ARB_GLX_create_context not supported!");
@@ -169,20 +169,18 @@ struct gl_platform *gl_platform_create(device_t device,
 		goto fail2;
 	}
 
-	blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION));
-
 	/* Initialize GLEW */
-	{
+	{ 	
+		glewExperimental = true;
 		GLenum err = glewInit();
+		
 		if (GLEW_OK != err) {
 			blog(LOG_ERROR, glewGetErrorString(err));
 			goto fail2;
 		}
 	}
 	
-	glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
-	glEnable(GL_DEBUG_OUTPUT);
-	glEnable(GL_CULL_FACE);
+	blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION));
 	
 	plat->swap.device = device;
 	plat->swap.info	  = *info;
@@ -195,6 +193,7 @@ struct gl_platform *gl_platform_create(device_t device,
 	return plat;
 	
 fail2:
+	glXMakeCurrent(display, None, NULL);
 	glXDestroyContext(display, plat->context);
 fail1: 
 	XFree(configs);
@@ -236,6 +235,12 @@ void device_leavecontext(device_t device)
 		blog(LOG_ERROR, "Failed to reset current context.");
 	}
 }
+
+void gl_update(device_t device)
+{
+	/* I don't know of anything we can do here. */
+}
+
 void device_load_swapchain(device_t device, swapchain_t swap) 
 {
 	if(!swap)