diff --git a/libobs-opengl/gl-helpers.c b/libobs-opengl/gl-helpers.c index 8a7a75708..c6e9012e7 100644 --- a/libobs-opengl/gl-helpers.c +++ b/libobs-opengl/gl-helpers.c @@ -57,13 +57,11 @@ bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, return success; } -static bool gl_copy_fbo(struct gs_device *device, - GLuint dst, GLenum dst_target, uint32_t dst_x, uint32_t dst_y, - GLuint src, GLenum src_target, uint32_t src_x, uint32_t src_y, - uint32_t width, uint32_t height, - enum gs_color_format format) +static bool gl_copy_fbo(struct gs_texture *dst, uint32_t dst_x, uint32_t dst_y, + struct gs_texture *src, uint32_t src_x, uint32_t src_y, + uint32_t width, uint32_t height) { - struct fbo_info *fbo = get_fbo(device, width, height, format); + struct fbo_info *fbo = get_fbo(src, width, height); GLint last_fbo; bool success = false; @@ -74,11 +72,11 @@ static bool gl_copy_fbo(struct gs_device *device, return false; if (!gl_bind_framebuffer(GL_READ_FRAMEBUFFER, fbo->fbo)) return false; - if (!gl_bind_texture(dst_target, dst)) + if (!gl_bind_texture(dst->gl_target, dst->texture)) goto fail; glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, - src_target, src, 0); + src->gl_target, src->texture, 0); if (!gl_success("glFrameBufferTexture2D")) goto fail; @@ -86,7 +84,7 @@ static bool gl_copy_fbo(struct gs_device *device, if (!gl_success("glReadBuffer")) goto fail; - glCopyTexSubImage2D(dst_target, 0, dst_x, dst_y, src_x, src_y, + glCopyTexSubImage2D(dst->gl_target, 0, dst_x, dst_y, src_x, src_y, width, height); if (!gl_success("glCopyTexSubImage2D")) goto fail; @@ -94,7 +92,7 @@ static bool gl_copy_fbo(struct gs_device *device, success = true; fail: - if (!gl_bind_texture(dst_target, 0)) + if (!gl_bind_texture(dst->gl_target, 0)) success = false; if (!gl_bind_framebuffer(GL_READ_FRAMEBUFFER, last_fbo)) success = false; @@ -102,29 +100,28 @@ fail: return success; } -bool gl_copy_texture(struct gs_device *device, - GLuint dst, GLenum dst_target, uint32_t dst_x, uint32_t dst_y, - GLuint src, GLenum src_target, uint32_t src_x, uint32_t src_y, - uint32_t width, uint32_t height, enum gs_color_format format) +bool gl_copy_texture(struct gs_device *device, struct gs_texture *dst, + uint32_t dst_x, uint32_t dst_y, struct gs_texture *src, + uint32_t src_x, uint32_t src_y, uint32_t width, + uint32_t height) { bool success = false; if (device->copy_type == COPY_TYPE_ARB) { - glCopyImageSubData(src, src_target, 0, src_x, src_y, 0, - dst, dst_target, 0, dst_x, dst_y, 0, - width, height, 1); + glCopyImageSubData(src->texture, src->gl_target, 0, src_x, + src_y, 0, dst->texture, dst->gl_target, 0, + dst_x, dst_y, 0, width, height, 1); success = gl_success("glCopyImageSubData"); } else if (device->copy_type == COPY_TYPE_NV) { - glCopyImageSubDataNV(src, src_target, 0, src_x, src_y, 0, - dst, dst_target, 0, dst_x, dst_y, 0, - width, height, 1); + glCopyImageSubDataNV(src->texture, src->gl_target, 0, src_x, + src_y, 0, dst->texture, dst->gl_target, 0, + dst_x, dst_y, 0, width, height, 1); success = gl_success("glCopyImageSubDataNV"); } else if (device->copy_type == COPY_TYPE_FBO_BLIT) { - success = gl_copy_fbo(device, dst, dst_target, dst_x, dst_y, - src, src_target, src_x, src_y, - width, height, format); + success = gl_copy_fbo(dst, dst_x, dst_y, src, src_x, src_y, + width, height); if (!success) blog(LOG_ERROR, "gl_copy_texture failed"); } diff --git a/libobs-opengl/gl-helpers.h b/libobs-opengl/gl-helpers.h index f1f912215..fe9959a3e 100644 --- a/libobs-opengl/gl-helpers.h +++ b/libobs-opengl/gl-helpers.h @@ -148,11 +148,10 @@ extern bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, uint32_t width, uint32_t height, uint32_t size, const uint8_t ***p_data); -extern bool gl_copy_texture(struct gs_device *device, - GLuint dst, GLenum dst_target, uint32_t dst_x, uint32_t dst_y, - GLuint src, GLenum src_target, uint32_t src_x, uint32_t src_y, - uint32_t width, uint32_t height, - enum gs_color_format format); +extern bool gl_copy_texture(struct gs_device *device, struct gs_texture *dst, + uint32_t dst_x, uint32_t dst_y, struct gs_texture *src, + uint32_t src_x, uint32_t src_y, uint32_t width, + uint32_t height); extern bool gl_create_buffer(GLenum target, GLuint *buffer, GLsizeiptr size, const GLvoid *data, GLenum usage); diff --git a/libobs-opengl/gl-stagesurf.c b/libobs-opengl/gl-stagesurf.c index aa1637cb4..35dd21258 100644 --- a/libobs-opengl/gl-stagesurf.c +++ b/libobs-opengl/gl-stagesurf.c @@ -124,7 +124,7 @@ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, if (!gl_bind_buffer(GL_PIXEL_PACK_BUFFER, dst->pack_buffer)) goto failed; - fbo = get_fbo(device, dst->width, dst->height, dst->format); + fbo = get_fbo(src, dst->width, dst->height); if (!gl_get_integer_v(GL_READ_FRAMEBUFFER_BINDING, &last_fbo)) goto failed_unbind_buffer; @@ -152,6 +152,8 @@ failed_unbind_buffer: failed: if (!success) blog(LOG_ERROR, "device_stage_texture (GL) failed"); + + UNUSED_PARAMETER(device); } #else diff --git a/libobs-opengl/gl-subsystem.c b/libobs-opengl/gl-subsystem.c index 063e1fdb7..65b9e3e4c 100644 --- a/libobs-opengl/gl-subsystem.c +++ b/libobs-opengl/gl-subsystem.c @@ -259,16 +259,10 @@ fail: void device_destroy(gs_device_t *device) { if (device) { - size_t i; - - for (i = 0; i < device->fbos.num; i++) - fbo_info_destroy(device->fbos.array[i]); - while (device->first_program) gs_program_destroy(device->first_program); da_free(device->proj_stack); - da_free(device->fbos); gl_platform_destroy(device->plat); bfree(device); } @@ -658,46 +652,37 @@ static bool get_tex_dimensions(gs_texture_t *tex, uint32_t *width, * This automatically manages FBOs so that render targets are always given * an FBO that matches their width/height/format to maximize optimization */ -struct fbo_info *get_fbo(struct gs_device *device, - uint32_t width, uint32_t height, enum gs_color_format format) +struct fbo_info *get_fbo(gs_texture_t *tex, uint32_t width, uint32_t height) { - size_t i; + if (tex->fbo && tex->fbo->width == width && + tex->fbo->height == height && + tex->fbo->format == tex->format) + return tex->fbo; + GLuint fbo; - struct fbo_info *ptr; - - for (i = 0; i < device->fbos.num; i++) { - ptr = device->fbos.array[i]; - - if (ptr->width == width && ptr->height == height && - ptr->format == format) - return ptr; - } - glGenFramebuffers(1, &fbo); if (!gl_success("glGenFramebuffers")) return NULL; - ptr = bmalloc(sizeof(struct fbo_info)); - ptr->fbo = fbo; - ptr->width = width; - ptr->height = height; - ptr->format = format; - ptr->cur_render_target = NULL; - ptr->cur_render_side = 0; - ptr->cur_zstencil_buffer = NULL; + tex->fbo = bmalloc(sizeof(struct fbo_info)); + tex->fbo->fbo = fbo; + tex->fbo->width = width; + tex->fbo->height = height; + tex->fbo->format = tex->format; + tex->fbo->cur_render_target = NULL; + tex->fbo->cur_render_side = 0; + tex->fbo->cur_zstencil_buffer = NULL; - da_push_back(device->fbos, &ptr); - return ptr; + return tex->fbo; } -static inline struct fbo_info *get_fbo_by_tex(struct gs_device *device, - gs_texture_t *tex) +static inline struct fbo_info *get_fbo_by_tex(gs_texture_t *tex) { uint32_t width, height; if (!get_tex_dimensions(tex, &width, &height)) return NULL; - return get_fbo(device, width, height, tex->format); + return get_fbo(tex, width, height); } static bool set_current_fbo(gs_device_t *device, struct fbo_info *fbo) @@ -783,7 +768,7 @@ static bool set_target(gs_device_t *device, gs_texture_t *tex, int side, if (!tex) return set_current_fbo(device, NULL); - fbo = get_fbo_by_tex(device, tex); + fbo = get_fbo_by_tex(tex); if (!fbo) return false; @@ -885,9 +870,8 @@ void device_copy_texture_region(gs_device_t *device, goto fail; } - if (!gl_copy_texture(device, dst->texture, dst->gl_target, dst_x, dst_y, - src->texture, src->gl_target, src_x, src_y, - nw, nh, src->format)) + if (!gl_copy_texture(device, dst, dst_x, dst_y, src, src_x, src_y, nw, + nh)) goto fail; return; diff --git a/libobs-opengl/gl-subsystem.h b/libobs-opengl/gl-subsystem.h index 446787646..ba6cf98d6 100644 --- a/libobs-opengl/gl-subsystem.h +++ b/libobs-opengl/gl-subsystem.h @@ -409,6 +409,7 @@ struct gs_texture { bool gen_mipmaps; gs_samplerstate_t *cur_sampler; + struct fbo_info *fbo; }; struct gs_texture_2d { @@ -501,12 +502,11 @@ struct gs_device { DARRAY(struct matrix4) proj_stack; - DARRAY(struct fbo_info*) fbos; struct fbo_info *cur_fbo; }; -extern struct fbo_info *get_fbo(struct gs_device *device, - uint32_t width, uint32_t height, enum gs_color_format format); +extern struct fbo_info *get_fbo(gs_texture_t *tex, uint32_t width, + uint32_t height); extern void gl_update(gs_device_t *device); diff --git a/libobs-opengl/gl-texture2d.c b/libobs-opengl/gl-texture2d.c index 1ad6c922f..da18b9f5c 100644 --- a/libobs-opengl/gl-texture2d.c +++ b/libobs-opengl/gl-texture2d.c @@ -138,6 +138,9 @@ void gs_texture_destroy(gs_texture_t *tex) if (tex->texture) gl_delete_textures(1, &tex->texture); + if (tex->fbo) + fbo_info_destroy(tex->fbo); + bfree(tex); } diff --git a/libobs-opengl/gl-texturecube.c b/libobs-opengl/gl-texturecube.c index f15d6b201..6086675e4 100644 --- a/libobs-opengl/gl-texturecube.c +++ b/libobs-opengl/gl-texturecube.c @@ -92,10 +92,11 @@ void gs_cubetexture_destroy(gs_texture_t *tex) if (!tex) return; - if (tex->texture) { - glDeleteTextures(1, &tex->texture); - gl_success("glDeleteTextures"); - } + if (tex->texture) + gl_delete_textures(1, &tex->texture); + + if (tex->fbo) + fbo_info_destroy(tex->fbo); bfree(tex); }