Seemingly creating and deleting them is crazy expensive on NVidia
(~3 ms for a create/delete pair), so
6dea8d2 caused a performance
regression at high frame rates. Now we instead keep one around per
context (they cannot be shared), which brings us basically back
to where we were performance-wise.
Reported by Christophe Thommeret.
if (owns_resource_pool) {
delete resource_pool;
}
if (owns_resource_pool) {
delete resource_pool;
}
+ for (map<void *, GLuint>::const_iterator fbo_it = fbos.begin();
+ fbo_it != fbos.end(); ++fbo_it) {
+ glDeleteFramebuffers(1, &fbo_it->second);
+ check_error();
+ }
}
Input *EffectChain::add_input(Input *input)
}
Input *EffectChain::add_input(Input *input)
// Save original viewport.
GLuint x = 0, y = 0;
GLuint fbo = 0;
// Save original viewport.
GLuint x = 0, y = 0;
GLuint fbo = 0;
+ void *context = get_gl_context_identifier();
if (width == 0 && height == 0) {
GLint viewport[4];
if (width == 0 && height == 0) {
GLint viewport[4];
check_error();
if (phases.size() > 1) {
check_error();
if (phases.size() > 1) {
- glGenFramebuffers(1, &fbo);
- check_error();
+ if (fbos.count(context) == 0) {
+ glGenFramebuffers(1, &fbo);
+ check_error();
+ fbos.insert(make_pair(context, fbo));
+ } else {
+ fbo = fbos[context];
+ }
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
check_error();
}
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
check_error();
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
check_error();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
check_error();
-
- if (fbo != 0) {
- glDeleteFramebuffers(1, &fbo);
- check_error();
- }
std::map<Effect *, Node *> node_map;
Effect *dither_effect;
std::map<Effect *, Node *> node_map;
Effect *dither_effect;
+ std::map<void *, GLuint> fbos; // One for each OpenGL context.
std::vector<Input *> inputs; // Also contained in nodes.
std::vector<Phase *> phases;
std::vector<Input *> inputs; // Also contained in nodes.
std::vector<Phase *> phases;
#include "init.h"
#include "util.h"
#include "init.h"
#include "util.h"
+#if defined(__DARWIN__)
+#include <OpenGL/OpenGL.h>
+#elif defined(WIN32)
+#include <GL/wglew.h>
+#else
+#include <GL/glxew.h>
+#endif
+
using namespace std;
namespace movit {
using namespace std;
namespace movit {
+void *get_gl_context_identifier()
+{
+#if defined(__DARWIN__)
+ return (void *)CGLGetCurrentContext();
+#elif defined(WIN32)
+ return (void *)wglGetCurrentContext();
+#else
+ return (void *)glXGetCurrentContext();
+#endif
+}
+
// If v is not already a power of two, return the first higher power of two.
unsigned next_power_of_two(unsigned v);
// If v is not already a power of two, return the first higher power of two.
unsigned next_power_of_two(unsigned v);
+// Get a pointer that represents the current OpenGL context, in a cross-platform way.
+// This is not intended for anything but identification (ie., so you can associate
+// different FBOs with different contexts); you should probably not try to cast it
+// back into anything you intend to pass into OpenGL.
+void *get_gl_context_identifier();
+
} // namespace movit
#ifdef NDEBUG
} // namespace movit
#ifdef NDEBUG