+ // Since uniforms belong to the program and not to the context,
+ // a given GLSL program number can't be used by more than one thread
+ // at a time. Thus, if two threads want to use the same program
+ // (usually because two EffectChains share them via caching),
+ // we will need to make a clone. use_glsl_program() makes such
+ // a clone if needed, calls glUseProgram(), and returns the real
+ // program number that was used; this must be given to
+ // unuse_glsl_program() to release it. unuse_glsl_program() does not
+ // actually change any OpenGL state, though.
+ GLuint use_glsl_program(GLuint glsl_program_num);
+ void unuse_glsl_program(GLuint instance_program_num);
+
+ // Allocate a 2D texture of the given internal format and dimensions,
+ // or fetch a previous used if possible. Unbinds GL_TEXTURE_2D afterwards.
+ // Keeps ownership of the texture; you must call release_2d_texture() instead
+ // of deleting it when you no longer want it.
+ GLuint create_2d_texture(GLint internal_format, GLsizei width, GLsizei height);
+ void release_2d_texture(GLuint texture_num);
+
+ // Allocate an FBO with the the given texture(s) bound as framebuffer attachment(s),
+ // or fetch a previous used if possible. Unbinds GL_FRAMEBUFFER afterwards.
+ // Keeps ownership of the FBO; you must call release_fbo() of deleting
+ // it when you no longer want it.
+ //
+ // NOTE: In principle, the FBO doesn't have a resolution or pixel format;
+ // you can bind almost whatever texture you want to it. However, changing
+ // textures can have an adverse effect on performance due to validation,
+ // in particular on NVidia cards. Also, keep in mind that FBOs are not
+ // shareable across contexts, so you must have the context that's supposed
+ // to own the FBO current when you create or release it.
+ GLuint create_fbo(GLuint texture0_num,
+ GLuint texture1_num = 0,
+ GLuint texture2_num = 0,
+ GLuint texture3_num = 0);
+ void release_fbo(GLuint fbo_num);
+
+ // Informs the ResourcePool that the current context is going away soon,
+ // and that any resources held for it in the freelist should be deleted.
+ //
+ // You do not need to do this for the last context; the regular destructor
+ // will take care of that. This means that if you only ever use one
+ // thread/context, you never need to call this function.
+ void clean_context();
+