浏览代码

add osx iosurface opengl integration

Palana 12 年之前
父节点
当前提交
74aa1c466b

+ 5 - 0
libobs-opengl/CMakeLists.txt

@@ -6,9 +6,14 @@ elseif(APPLE AND UNIX)
 	set_source_files_properties(${libobs_opengl_platform_objc_src}
 	set_source_files_properties(${libobs_opengl_platform_objc_src}
 		PROPERTIES LANGUAGE C)
 		PROPERTIES LANGUAGE C)
 	set(libobs_opengl_platform_src ${libobs_opengl_platform_objc_src})
 	set(libobs_opengl_platform_src ${libobs_opengl_platform_objc_src})
+	
 	find_library(COCOA Cocoa)
 	find_library(COCOA Cocoa)
 	include_directories(${COCOA})
 	include_directories(${COCOA})
 	link_libraries(${COCOA})
 	link_libraries(${COCOA})
+	
+	find_library(IOSURF IOSurface)
+	include_directories(${IOSURF})
+	link_libraries(${IOSURF})
 else()
 else()
 endif()
 endif()
 
 

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

@@ -252,3 +252,106 @@ void gl_getclientsize(struct gs_swap_chain *swap, uint32_t *width,
 	if(width) *width = swap->info.cx;
 	if(width) *width = swap->info.cx;
 	if(height) *height = swap->info.cy;
 	if(height) *height = swap->info.cy;
 }
 }
+
+texture_t texture_create_from_iosurface(device_t device, void *iosurf)
+{
+	IOSurfaceRef ref = (IOSurfaceRef)iosurf;
+	struct gs_texture_2d *tex = bmalloc(sizeof(struct gs_texture_2d));
+	memset(tex, 0, sizeof(struct gs_texture_2d));
+
+	const enum gs_color_format color_format = GS_BGRA;
+
+	tex->base.device             = device;
+	tex->base.type               = GS_TEXTURE_2D;
+	tex->base.format             = GS_BGRA;
+	tex->base.levels             = 1;
+	tex->base.gl_format          = convert_gs_format(color_format);
+	tex->base.gl_internal_format = convert_gs_internal_format(color_format);
+	tex->base.gl_type            = GL_UNSIGNED_INT_8_8_8_8_REV;
+	tex->base.gl_target          = GL_TEXTURE_RECTANGLE;
+	tex->base.is_dynamic         = false;
+	tex->base.is_render_target   = false;
+	tex->base.gen_mipmaps        = false;
+	tex->width                   = IOSurfaceGetWidth(ref);
+	tex->height                  = IOSurfaceGetHeight(ref);
+
+	if (!gl_gen_textures(1, &tex->base.texture))
+		goto fail;
+
+	if (!gl_bind_texture(tex->base.gl_target, tex->base.texture))
+		goto fail;
+
+	CGLError err = CGLTexImageIOSurface2D(
+			[[NSOpenGLContext currentContext] CGLContextObj],
+			tex->base.gl_target,
+			tex->base.gl_internal_format,
+			tex->width, tex->height,
+			tex->base.gl_format,
+			tex->base.gl_type,
+			ref, 0);
+	
+	if(err != kCGLNoError) {
+		blog(LOG_ERROR, "CGLTexImageIOSurface2D: %u, %s"
+			        " (texture_create_from_iosurface)",
+				err, CGLErrorString(err));
+
+		gl_success("CGLTexImageIOSurface2D");
+		goto fail;
+	}
+
+	if (!gl_tex_param_i(tex->base.gl_target,
+				GL_TEXTURE_MAX_LEVEL, 0))
+		goto fail;
+
+	if (!gl_bind_texture(tex->base.gl_target, 0))
+		goto fail;
+
+	return (texture_t)tex;
+
+fail:
+	texture_destroy((texture_t)tex);
+	blog(LOG_ERROR, "texture_create_from_iosurface (GL) failed");
+	return NULL;
+}
+
+bool texture_rebind_iosurface(texture_t texture, void *iosurf)
+{
+	if (!texture)
+		return false;
+
+	if (!iosurf)
+		return false;
+
+	struct gs_texture_2d *tex = (struct gs_texture_2d*)texture;
+	IOSurfaceRef ref = (IOSurfaceRef)iosurf;
+
+	if (tex->width != IOSurfaceGetWidth(ref) ||
+			tex->height != IOSurfaceGetHeight(ref))
+		return false;
+
+	if (!gl_bind_texture(tex->base.gl_target, tex->base.texture))
+		return false;
+
+	CGLError err = CGLTexImageIOSurface2D(
+			[[NSOpenGLContext currentContext] CGLContextObj],
+			tex->base.gl_target,
+			tex->base.gl_internal_format,
+			tex->width, tex->height,
+			tex->base.gl_format,
+			tex->base.gl_type,
+			ref, 0);
+	
+	if(err != kCGLNoError) {
+		blog(LOG_ERROR, "CGLTexImageIOSurface2D: %u, %s"
+			        " (texture_rebind_iosurface)",
+				err, CGLErrorString(err));
+
+		gl_success("CGLTexImageIOSurface2D");
+		return false;
+	}
+
+	if (!gl_bind_texture(tex->base.gl_target, 0))
+		return false;
+
+	return true;
+}

+ 5 - 0
libobs-opengl/gl-exports.h

@@ -188,3 +188,8 @@ EXPORT void shader_settexture(shader_t shader, sparam_t param, texture_t val);
 EXPORT void shader_setval(shader_t shader, sparam_t param, const void *val,
 EXPORT void shader_setval(shader_t shader, sparam_t param, const void *val,
 		size_t size);
 		size_t size);
 EXPORT void shader_setdefault(shader_t shader, sparam_t param);
 EXPORT void shader_setdefault(shader_t shader, sparam_t param);
+
+#ifdef __APPLE__
+EXPORT texture_t texture_create_from_iosurface(device_t device, void *iosurf);
+EXPORT bool texture_rebind_iosurface(texture_t texture, void *iosurf);
+#endif

+ 1 - 0
libobs-opengl/makefile.am

@@ -33,6 +33,7 @@ libobs_opengl_la_SOURCES = gl-helpers.c \
 
 
 if OS_OSX
 if OS_OSX
 libobs_opengl_la_SOURCES += gl-cocoa.m
 libobs_opengl_la_SOURCES += gl-cocoa.m
+libobs_opengl_la_LDFLAGS += -framework Cocoa -framework IOSurface
 endif
 endif
 
 
 if OS_WIN
 if OS_WIN

+ 4 - 0
libobs/graphics/graphics-imports.c

@@ -165,5 +165,9 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
 	GRAPHICS_IMPORT(shader_setval);
 	GRAPHICS_IMPORT(shader_setval);
 	GRAPHICS_IMPORT(shader_setdefault);
 	GRAPHICS_IMPORT(shader_setdefault);
 
 
+	/* OSX/Cocoa specific functions */
+	GRAPHICS_IMPORT_OPTIONAL(texture_create_from_iosurface);
+	GRAPHICS_IMPORT_OPTIONAL(texture_rebind_iosurface);
+
 	return success;
 	return success;
 }
 }

+ 4 - 0
libobs/graphics/graphics-internal.h

@@ -201,6 +201,10 @@ struct gs_exports {
 	void (*shader_setval)(shader_t shader, sparam_t param, const void *val,
 	void (*shader_setval)(shader_t shader, sparam_t param, const void *val,
 			size_t size);
 			size_t size);
 	void (*shader_setdefault)(shader_t shader, sparam_t param);
 	void (*shader_setdefault)(shader_t shader, sparam_t param);
+
+	/* OSX/Cocoa specific functions */
+	texture_t (*texture_create_from_iosurface)(device_t dev, void *iosurf);
+	bool (*texture_rebind_iosurface)(texture_t texture, void *iosurf);
 };
 };
 
 
 struct graphics_subsystem {
 struct graphics_subsystem {

+ 22 - 0
libobs/graphics/graphics.c

@@ -1589,3 +1589,25 @@ enum gs_index_type indexbuffer_gettype(indexbuffer_t indexbuffer)
 {
 {
 	return thread_graphics->exports.indexbuffer_gettype(indexbuffer);
 	return thread_graphics->exports.indexbuffer_gettype(indexbuffer);
 }
 }
+
+/** Platform specific functions */
+texture_t gs_create_texture_from_iosurface(void *iosurf)
+{
+	graphics_t graphics = thread_graphics;
+	if (!graphics->exports.texture_create_from_iosurface)
+		return NULL;
+
+	return graphics->exports.texture_create_from_iosurface(
+			graphics->device, iosurf);
+}
+
+bool texture_rebind_iosurface(texture_t texture, void *iosurf)
+{
+	graphics_t graphics = thread_graphics;
+	if (!graphics->exports.texture_rebind_iosurface)
+		return false;
+
+	return graphics->exports.texture_rebind_iosurface(texture, iosurf);
+}
+
+

+ 5 - 0
libobs/graphics/graphics.h

@@ -678,6 +678,11 @@ EXPORT void     *indexbuffer_getdata(indexbuffer_t indexbuffer);
 EXPORT size_t   indexbuffer_numindices(indexbuffer_t indexbuffer);
 EXPORT size_t   indexbuffer_numindices(indexbuffer_t indexbuffer);
 EXPORT enum gs_index_type indexbuffer_gettype(indexbuffer_t indexbuffer);
 EXPORT enum gs_index_type indexbuffer_gettype(indexbuffer_t indexbuffer);
 
 
+/** platform specific function for creating (GL_TEXTURE_RECTANGLE) textures
+ * from shared surface resources */
+EXPORT texture_t gs_create_texture_from_iosurface(void *iosurf);
+EXPORT bool     texture_rebind_iosurface(texture_t texture, void *iosurf);
+
 /* inline functions used by modules */
 /* inline functions used by modules */
 
 
 static inline uint32_t gs_get_format_bpp(enum gs_color_format format)
 static inline uint32_t gs_get_format_bpp(enum gs_color_format format)