Use glBlitFramebuffer when available to blit framebuffer

This commit is contained in:
raven02 2014-05-09 22:01:30 +08:00 committed by Henrik Rydgard
parent cf7229e05e
commit 68548856fd

View file

@ -1236,8 +1236,7 @@ void FramebufferManager::ReadFramebufferToMemory(VirtualFramebuffer *vfb, bool s
} }
} }
// TODO: If glBlitFramebuffer is available, we can take a shortcut. If, in addition, the dimensions // TODO: If dimensions are the same, we can use glCopyImageSubData.
// are the same, we can use glCopyImageSubData.
void FramebufferManager::BlitFramebuffer_(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h) { void FramebufferManager::BlitFramebuffer_(VirtualFramebuffer *dst, int dstX, int dstY, VirtualFramebuffer *src, int srcX, int srcY, int w, int h) {
if (!dst->fbo) { if (!dst->fbo) {
ERROR_LOG_REPORT_ONCE(dstfbozero, SCEGE, "BlitFramebuffer_: dst->fbo == 0"); ERROR_LOG_REPORT_ONCE(dstfbozero, SCEGE, "BlitFramebuffer_: dst->fbo == 0");
@ -1252,32 +1251,43 @@ void FramebufferManager::BlitFramebuffer_(VirtualFramebuffer *dst, int dstX, int
} }
fbo_bind_as_render_target(dst->fbo); fbo_bind_as_render_target(dst->fbo);
fbo_bind_color_as_texture(src->fbo, 0);
// glCheckFramebufferStatus should only be called at creation time. Here it's just silly - we just bound a draw buffer above.
#if 0 #ifndef USING_GLES2
if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { if (gl_extensions.FBO_ARB) {
ERROR_LOG(SCEGE, "Incomplete target framebuffer, aborting blit"); #else
fbo_unbind(); if (gl_extensions.GLES3 || gl_extensions.NV_framebuffer_blit) {
if (gl_extensions.FBO_ARB) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
return;
}
#endif #endif
// Make sure our 2D drawing program is ready. Compiles only if not already compiled.
CompileDraw2DProgram();
glstate.viewport.set(0, 0, dst->width, dst->height); #ifdef MAY_HAVE_GLES3
DisableState(); fbo_bind_for_read(src->fbo);
if (gl_extensions.GLES3) {
glBlitFramebuffer(0, src->renderHeight, src->renderWidth, 0, 0, 0, dst->width, dst->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
#if defined(ANDROID) // We only support this extension on Android, it's not even available on PC.
else if (gl_extensions.NV_framebuffer_blit) {
glBlitFramebufferNV(0, src->renderHeight, src->renderWidth, 0, 0, 0, dst->width, dst->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
#endif // defined(ANDROID)
// The first four coordinates are relative to the 6th and 7th arguments of DrawActiveTexture. } else {
// Should maybe revamp that interface. fbo_bind_color_as_texture(src->fbo, 0);
float srcW = src->width;
float srcH = src->height; // Make sure our 2D drawing program is ready. Compiles only if not already compiled.
DrawActiveTexture(0, dstX, dstY, w, h, dst->width, dst->height, false, srcX / srcW, srcY / srcH, (srcX + w) / srcW, (srcY + h) / srcH, draw2dprogram_); CompileDraw2DProgram();
glstate.viewport.set(0, 0, dst->width, dst->height);
DisableState();
// The first four coordinates are relative to the 6th and 7th arguments of DrawActiveTexture.
// Should maybe revamp that interface.
float srcW = src->width;
float srcH = src->height;
DrawActiveTexture(0, dstX, dstY, w, h, dst->width, dst->height, false, srcX / srcW, srcY / srcH, (srcX + w) / srcW, (srcY + h) / srcH, draw2dprogram_);
glBindTexture(GL_TEXTURE_2D, 0);
}
#endif // MAY_HAVE_GLES3
glBindTexture(GL_TEXTURE_2D, 0);
fbo_unbind(); fbo_unbind();
} }