+#include <stdexcept>
+#include <msp/gl/extensions/arb_occlusion_query.h>
+#include <msp/gl/extensions/arb_occlusion_query2.h>
+#include "query.h"
+#include "renderer.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+QueryPool::QueryPool(QueryType t, unsigned s):
+ type(t),
+ gl_type(get_gl_query_type(type))
+{
+ if(type==OCCLUSION_QUERY)
+ {
+ static Require req(ARB_occlusion_query);
+ static Require req2(ARB_occlusion_query2);
+ }
+
+ resize(s);
+}
+
+QueryPool::~QueryPool()
+{
+ glDeleteQueries(queries.size(), queries.data());
+}
+
+void QueryPool::resize(unsigned s)
+{
+ if(s<queries.size())
+ glDeleteQueries(queries.size()-s, queries.data()+s);
+
+ unsigned old_size = queries.size();
+ queries.resize(s);
+ if(s>old_size)
+ glGenQueries(s-old_size, queries.data()+old_size);
+}
+
+unsigned QueryPool::get_result(unsigned i) const
+{
+ unsigned result = 0;
+ glGetQueryObjectuiv(queries[i], GL_QUERY_RESULT, &result);
+ return result;
+}
+
+
+QueryPool::Activate::Activate(Renderer &r, const QueryPool &p, unsigned i):
+ renderer(r),
+ pool(p),
+ index(i)
+{
+ renderer.begin_query(pool, index);
+}
+
+QueryPool::Activate::~Activate()
+{
+ renderer.end_query(pool, index);
+}
+
+
+unsigned get_gl_query_type(QueryType t)
+{
+ switch(t)
+ {
+ case OCCLUSION_QUERY: return GL_ANY_SAMPLES_PASSED;
+ default: throw invalid_argument("get_gl_query_type");
+ }
+}
+
+} // namespace GL
+} // namespace Msp