diff --git a/libobs-opengl/gl-stagesurf.c b/libobs-opengl/gl-stagesurf.c index 6415f3852..7f03064bc 100644 --- a/libobs-opengl/gl-stagesurf.c +++ b/libobs-opengl/gl-stagesurf.c @@ -107,6 +107,58 @@ static bool can_stage(struct gs_stage_surface *dst, struct gs_texture_2d *src) return true; } +#ifdef __APPLE__ + +/* Apparently for mac, PBOs won't do an asynchronous transfer unless you use + * FBOs along with glReadPixels, which is really dumb. */ +void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, + gs_texture_t *src) +{ + struct gs_texture_2d *tex2d = (struct gs_texture_2d *)src; + struct fbo_info *fbo; + GLint last_fbo; + bool success = false; + + if (!can_stage(dst, tex2d)) + goto failed; + + if (!gl_bind_buffer(GL_PIXEL_PACK_BUFFER, dst->pack_buffer)) + goto failed; + + fbo = get_fbo(src, dst->width, dst->height); + + if (!gl_get_integer_v(GL_READ_FRAMEBUFFER_BINDING, &last_fbo)) + goto failed_unbind_buffer; + if (!gl_bind_framebuffer(GL_READ_FRAMEBUFFER, fbo->fbo)) + goto failed_unbind_buffer; + + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, + src->gl_target, src->texture, 0); + if (!gl_success("glFrameBufferTexture2D")) + goto failed_unbind_all; + + glReadPixels(0, 0, dst->width, dst->height, dst->gl_format, + dst->gl_type, 0); + if (!gl_success("glReadPixels")) + goto failed_unbind_all; + + success = true; + +failed_unbind_all: + gl_bind_framebuffer(GL_READ_FRAMEBUFFER, last_fbo); + +failed_unbind_buffer: + gl_bind_buffer(GL_PIXEL_PACK_BUFFER, 0); + +failed: + if (!success) + blog(LOG_ERROR, "device_stage_texture (GL) failed"); + + UNUSED_PARAMETER(device); +} + +#else + void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, gs_texture_t *src) { @@ -135,6 +187,8 @@ failed: UNUSED_PARAMETER(device); } +#endif + uint32_t gs_stagesurface_get_width(const gs_stagesurf_t *stagesurf) { return stagesurf->width;