libobs/graphics: Add NV12 texture support
This commit is contained in:
@@ -171,6 +171,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
||||
GRAPHICS_IMPORT(gs_shader_set_default);
|
||||
GRAPHICS_IMPORT(gs_shader_set_next_sampler);
|
||||
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_nv12_available);
|
||||
|
||||
/* OSX/Cocoa specific functions */
|
||||
#ifdef __APPLE__
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_from_iosurface);
|
||||
@@ -192,6 +194,8 @@ bool load_graphics_imports(struct gs_exports *exports, void *module,
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_get_shared_handle);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_acquire_sync);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_release_sync);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_texture_create_nv12);
|
||||
GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_nv12);
|
||||
#endif
|
||||
|
||||
return success;
|
||||
|
@@ -232,6 +232,8 @@ struct gs_exports {
|
||||
void (*gs_shader_set_next_sampler)(gs_sparam_t *param,
|
||||
gs_samplerstate_t *sampler);
|
||||
|
||||
bool (*device_nv12_available)(gs_device_t *device);
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* OSX/Cocoa specific functions */
|
||||
gs_texture_t *(*device_texture_create_from_iosurface)(gs_device_t *dev,
|
||||
@@ -265,6 +267,12 @@ struct gs_exports {
|
||||
int (*device_texture_acquire_sync)(gs_texture_t *tex, uint64_t key,
|
||||
uint32_t ms);
|
||||
int (*device_texture_release_sync)(gs_texture_t *tex, uint64_t key);
|
||||
bool (*device_texture_create_nv12)(gs_device_t *device,
|
||||
gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
||||
uint32_t width, uint32_t height, uint32_t flags);
|
||||
|
||||
gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device,
|
||||
uint32_t width, uint32_t height);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@@ -2545,6 +2545,18 @@ enum gs_index_type gs_indexbuffer_get_type(const gs_indexbuffer_t *indexbuffer)
|
||||
return thread_graphics->exports.gs_indexbuffer_get_type(indexbuffer);
|
||||
}
|
||||
|
||||
bool gs_nv12_available(void)
|
||||
{
|
||||
if (!gs_valid("gs_nv12_available"))
|
||||
return false;
|
||||
|
||||
if (!thread_graphics->exports.device_nv12_available)
|
||||
return false;
|
||||
|
||||
return thread_graphics->exports.device_nv12_available(
|
||||
thread_graphics->device);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
/** Platform specific functions */
|
||||
@@ -2726,4 +2738,64 @@ int gs_texture_release_sync(gs_texture_t *tex, uint64_t key)
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
||||
uint32_t width, uint32_t height, uint32_t flags)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
bool success = false;
|
||||
|
||||
if (!gs_valid("gs_texture_create_nv12"))
|
||||
return false;
|
||||
|
||||
if ((width & 1) == 1 || (height & 1) == 1) {
|
||||
blog(LOG_ERROR, "NV12 textures must have dimensions "
|
||||
"divisible by 2.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (graphics->exports.device_texture_create_nv12) {
|
||||
success = graphics->exports.device_texture_create_nv12(
|
||||
graphics->device, tex_y, tex_uv,
|
||||
width, height, flags);
|
||||
if (success)
|
||||
return true;
|
||||
}
|
||||
|
||||
*tex_y = gs_texture_create(width, height, GS_R8, 1, NULL, flags);
|
||||
*tex_uv = gs_texture_create(width / 2, height / 2, GS_R8G8, 1, NULL,
|
||||
flags);
|
||||
|
||||
if (!*tex_y || !*tex_uv) {
|
||||
if (*tex_y)
|
||||
gs_texture_destroy(*tex_y);
|
||||
if (*tex_uv)
|
||||
gs_texture_destroy(*tex_uv);
|
||||
*tex_y = NULL;
|
||||
*tex_uv = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, uint32_t height)
|
||||
{
|
||||
graphics_t *graphics = thread_graphics;
|
||||
|
||||
if (!gs_valid("gs_stagesurface_create_nv12"))
|
||||
return NULL;
|
||||
|
||||
if ((width & 1) == 1 || (height & 1) == 1) {
|
||||
blog(LOG_ERROR, "NV12 textures must have dimensions "
|
||||
"divisible by 2.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (graphics->exports.device_stagesurface_create_nv12)
|
||||
return graphics->exports.device_stagesurface_create_nv12(
|
||||
graphics->device, width, height);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -71,7 +71,8 @@ enum gs_color_format {
|
||||
GS_R32F,
|
||||
GS_DXT1,
|
||||
GS_DXT3,
|
||||
GS_DXT5
|
||||
GS_DXT5,
|
||||
GS_R8G8,
|
||||
};
|
||||
|
||||
enum gs_zstencil_format {
|
||||
@@ -758,6 +759,8 @@ EXPORT size_t gs_indexbuffer_get_num_indices(
|
||||
EXPORT enum gs_index_type gs_indexbuffer_get_type(
|
||||
const gs_indexbuffer_t *indexbuffer);
|
||||
|
||||
EXPORT bool gs_nv12_available(void);
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
/** platform specific function for creating (GL_TEXTURE_RECTANGLE) textures
|
||||
@@ -814,6 +817,12 @@ EXPORT int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms)
|
||||
*/
|
||||
EXPORT int gs_texture_release_sync(gs_texture_t *tex, uint64_t key);
|
||||
|
||||
EXPORT bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv,
|
||||
uint32_t width, uint32_t height, uint32_t flags);
|
||||
|
||||
EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12(
|
||||
uint32_t width, uint32_t height);
|
||||
|
||||
#endif
|
||||
|
||||
/* inline functions used by modules */
|
||||
@@ -838,6 +847,7 @@ static inline uint32_t gs_get_format_bpp(enum gs_color_format format)
|
||||
case GS_DXT1: return 4;
|
||||
case GS_DXT3: return 8;
|
||||
case GS_DXT5: return 8;
|
||||
case GS_R8G8: return 16;
|
||||
case GS_UNKNOWN: return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user