|
@@ -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;
|