X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=resource_pool.h;fp=resource_pool.h;h=a6e4327b2e953ca5747f6b6dfac8d6e8811426f3;hb=edb0700c0a8ea225ce9add1cb4f70d42af6de381;hp=0000000000000000000000000000000000000000;hpb=cf1beb1c14061e754483f99a245ecfdde5cb7b79;p=movit diff --git a/resource_pool.h b/resource_pool.h new file mode 100644 index 0000000..a6e4327 --- /dev/null +++ b/resource_pool.h @@ -0,0 +1,69 @@ +#ifndef _MOVIT_RESOURCE_POOL_H +#define _MOVIT_RESOURCE_POOL_H 1 + +// A ResourcePool governs resources that are shared between multiple EffectChains; +// in particular, resources that might be expensive to acquire or hold. Thus, +// if you have many EffectChains, hooking them up to the same ResourcePool is +// probably a good idea. +// +// However, hooking an EffectChain to a ResourcePool extends the OpenGL context +// demands (see effect_chain.h) to that of the ResourcePool; all chains must then +// only be used in OpenGL contexts sharing resources with each other. This is +// the reason why there isn't just one global ResourcePool singleton (although +// most practical users will just want one). +// +// Thread-safety: All functions except the constructor and destructor can be +// safely called from multiple threads at the same time, provided they have +// separate (but sharing) OpenGL contexts. + +#include +#include +#include +#include +#include +#include + +class ResourcePool { +public: + // program_freelist_max_length is how many compiled programs that are unused to keep + // around after they are no longer in use (in case another EffectChain + // wants that exact program later). Shaders are expensive to compile and do not + // need a lot of resources to keep around, so this should be a reasonable number. + ResourcePool(size_t program_freelist_max_length = 100); + ~ResourcePool(); + + // All remaining functions are intended for calls from EffectChain only. + + // Compile the given vertex+fragment shader pair, or fetch an already + // compiled program from the cache if possible. Keeps ownership of the + // program; you must call release_glsl_program() instead of deleting it + // when you no longer want it. + GLuint compile_glsl_program(const std::string& vertex_shader, const std::string& fragment_shader); + void release_glsl_program(GLuint glsl_program_num); + +private: + // Delete the given program and both its shaders. + void delete_program(GLuint program_num); + + // Protects all the other elements in the class. + pthread_mutex_t lock; + + size_t program_freelist_max_length; + + // A mapping from vertex/fragment shader source strings to compiled program number. + std::map, GLuint> programs; + + // A mapping from compiled program number to number of current users. + // Once this reaches zero, the program is taken out of this map and instead + // put on the freelist (after which it may be deleted). + std::map program_refcount; + + // A mapping from program number to vertex and fragment shaders. + std::map > program_shaders; + + // A list of programs that are no longer in use, most recently freed first. + // Once this reaches , + std::list program_freelist; +}; + +#endif // !defined(_MOVIT_RESOURCE_POOL_H)