1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 **************************************************************************/
26 // File: vogl_query_state.cpp
27 #include "vogl_query_state.h"
29 vogl_query_state::vogl_query_state()
30 : m_snapshot_handle(0),
33 m_has_been_begun(false),
39 vogl_query_state::~vogl_query_state()
44 bool vogl_query_state::snapshot(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 handle, GLenum target)
48 VOGL_NOTE_UNUSED(remapper);
53 VOGL_ASSERT(handle <= cUINT32_MAX);
55 m_snapshot_handle = static_cast<GLuint>(handle);
57 m_has_been_begun = GL_ENTRYPOINT(glIsQuery)(static_cast<GLuint>(handle)) != 0;
59 if (target != GL_NONE)
61 if (context_info.supports_extension("GL_ARB_timer_query") && GL_ENTRYPOINT(glGetQueryObjecti64v))
64 GL_ENTRYPOINT(glGetQueryObjecti64v)(m_snapshot_handle, GL_QUERY_RESULT, &result);
65 m_prev_result = result;
70 GL_ENTRYPOINT(glGetQueryObjectuiv)(m_snapshot_handle, GL_QUERY_RESULT, &prev_result32);
71 m_prev_result = prev_result32;
75 m_get_result_status = vogl_check_gl_error();
82 bool vogl_query_state::restore(const vogl_context_info &context_info, vogl_handle_remapper &remapper, GLuint64 &handle) const
86 VOGL_NOTE_UNUSED(context_info);
91 bool created_handle = false;
96 GL_ENTRYPOINT(glGenQueries)(1, &handle32);
97 if ((vogl_check_gl_error()) || (!handle32))
101 remapper.declare_handle(VOGL_NAMESPACE_QUERIES, m_snapshot_handle, handle, m_target);
102 VOGL_ASSERT(remapper.remap_handle(VOGL_NAMESPACE_QUERIES, m_snapshot_handle) == handle);
104 created_handle = true;
107 // m_target will be GL_NONE if the query has been genned but not begun up to this point.
108 if ((m_target != GL_NONE) && (m_has_been_begun))
110 GLuint prev_query = 0;
111 GL_ENTRYPOINT(glGetQueryiv)(m_target, GL_CURRENT_QUERY, reinterpret_cast<GLint *>(&prev_query));
114 VOGL_ASSERT(handle <= cUINT32_MAX);
116 // Begin end the restore query, so it becomes a valid name.
117 GL_ENTRYPOINT(glBeginQuery)(m_target, static_cast<GLuint>(handle));
118 if (vogl_check_gl_error())
121 GL_ENTRYPOINT(glEndQuery)(m_target);
122 if (vogl_check_gl_error())
127 // Now begin/end the original query so it's active again. The query API sucks.
128 GL_ENTRYPOINT(glBeginQuery)(m_target, prev_query);
131 GL_ENTRYPOINT(glEndQuery)(m_target);
139 if ((handle) && (created_handle))
141 remapper.delete_handle_and_object(VOGL_NAMESPACE_QUERIES, m_snapshot_handle, handle);
143 //GLuint handle32 = static_cast<GLuint>(handle);
144 //GL_ENTRYPOINT(glDeleteQueries)(1, &handle32);
145 //VOGL_CHECK_GL_ERROR;
153 bool vogl_query_state::remap_handles(vogl_handle_remapper &remapper)
160 m_snapshot_handle = static_cast<GLuint>(remapper.remap_handle(VOGL_NAMESPACE_QUERIES, m_snapshot_handle));
165 void vogl_query_state::clear()
169 m_snapshot_handle = 0;
172 m_get_result_status = GL_NONE;
173 m_has_been_begun = false;
177 bool vogl_query_state::serialize(json_node &node, vogl_blob_manager &blob_manager) const
181 VOGL_NOTE_UNUSED(blob_manager);
186 node.add_key_value("handle", m_snapshot_handle);
187 node.add_key_value("target", g_gl_enums.find_name(m_target, "gl"));
188 node.add_key_value("prev_result", m_prev_result);
189 node.add_key_value("has_been_begun", m_has_been_begun);
194 bool vogl_query_state::deserialize(const json_node &node, const vogl_blob_manager &blob_manager)
198 VOGL_NOTE_UNUSED(blob_manager);
202 m_snapshot_handle = node.value_as_uint32("handle");
203 if (!m_snapshot_handle)
208 m_target = vogl_get_json_value_as_enum(node, "target");
209 if (!utils::is_in_set(static_cast<int>(m_target), GL_NONE, GL_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED, GL_PRIMITIVES_GENERATED, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_TIME_ELAPSED))
215 m_prev_result = node.value_as_int64("prev_result");
216 m_has_been_begun = node.value_as_bool("has_been_begun");
223 bool vogl_query_state::compare_restorable_state(const vogl_gl_object_state &rhs_obj) const
227 if ((!m_is_valid) || (!rhs_obj.is_valid()))
230 if (rhs_obj.get_type() != cGLSTQuery)
233 const vogl_query_state &rhs = static_cast<const vogl_query_state &>(rhs_obj);
238 // We can't restore the prev result, so don't bother comparing it, so there's not much to do here.
239 return (m_target == rhs.m_target) && (m_has_been_begun == rhs.m_has_been_begun);