Index: Source/modules/webgl/EXTDisjointTimerQuery.cpp |
diff --git a/Source/modules/webgl/EXTDisjointTimerQuery.cpp b/Source/modules/webgl/EXTDisjointTimerQuery.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..30a7b157eca209fa155366a9fde8f0b8f2200e82 |
--- /dev/null |
+++ b/Source/modules/webgl/EXTDisjointTimerQuery.cpp |
@@ -0,0 +1,218 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "config.h" |
+ |
+#include "modules/webgl/EXTDisjointTimerQuery.h" |
+ |
+#include "bindings/modules/v8/WebGLAny.h" |
+#include "modules/webgl/WebGLRenderingContextBase.h" |
+#include "modules/webgl/WebGLTimerQueryEXT.h" |
+ |
+namespace blink { |
+ |
+EXTDisjointTimerQuery::~EXTDisjointTimerQuery() |
+{ |
+} |
+ |
+WebGLExtensionName EXTDisjointTimerQuery::name() const |
+{ |
+ return EXTDisjointTimerQueryName; |
+} |
+ |
+EXTDisjointTimerQuery* EXTDisjointTimerQuery::create(WebGLRenderingContextBase* context) |
+{ |
+ EXTDisjointTimerQuery* o = new EXTDisjointTimerQuery(context); |
+ return o; |
+} |
+ |
+bool EXTDisjointTimerQuery::supported(WebGLRenderingContextBase* context) |
+{ |
+ return context->extensionsUtil()->supportsExtension("GL_EXT_disjoint_timer_query"); |
+} |
+ |
+const char* EXTDisjointTimerQuery::extensionName() |
+{ |
+ return "EXT_disjoint_timer_query"; |
+} |
+ |
+WebGLTimerQueryEXT* EXTDisjointTimerQuery::createQueryEXT() |
+{ |
+ WebGLExtensionScopedContext scoped(this); |
+ if (scoped.isLost()) |
+ return nullptr; |
+ |
+ WebGLTimerQueryEXT* o = WebGLTimerQueryEXT::create(scoped.context()); |
+ scoped.context()->addContextObject(o); |
+ return o; |
+} |
+ |
+void EXTDisjointTimerQuery::deleteQueryEXT(WebGLTimerQueryEXT* query) |
+{ |
+ WebGLExtensionScopedContext scoped(this); |
+ if (!query || scoped.isLost()) |
+ return; |
+ query->deleteObject(scoped.context()->webContext()); |
+ |
+ if (query == m_currentElapsedQuery) |
+ m_currentElapsedQuery.clear(); |
+} |
+ |
+GLboolean EXTDisjointTimerQuery::isQueryEXT(WebGLTimerQueryEXT* query) |
+{ |
+ WebGLExtensionScopedContext scoped(this); |
+ if (!query || scoped.isLost() || query->isDeleted() || !query->validate(0, scoped.context())) { |
+ return false; |
+ } |
+ |
+ return scoped.context()->webContext()->isQueryEXT(query->object()); |
+} |
+ |
+void EXTDisjointTimerQuery::beginQueryEXT(GLenum target, WebGLTimerQueryEXT* query) |
+{ |
+ WebGLExtensionScopedContext scoped(this); |
+ if (scoped.isLost()) |
+ return; |
+ |
+ if (!query || query->isDeleted() || !query->validate(0, scoped.context())) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_OPERATION); |
+ return; |
+ } |
+ |
+ if (target != GL_TIME_ELAPSED_EXT) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_ENUM); |
+ return; |
+ } |
+ |
+ if (m_currentElapsedQuery.get()) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_OPERATION); |
+ return; |
+ } |
+ |
+ if (query->hasTarget() && query->target() != target) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_OPERATION); |
+ return; |
+ } |
+ |
+ scoped.context()->webContext()->beginQueryEXT(target, query->object()); |
+ query->setTarget(target); |
+ m_currentElapsedQuery = query; |
+} |
+ |
+void EXTDisjointTimerQuery::endQueryEXT(GLenum target) |
+{ |
+ WebGLExtensionScopedContext scoped(this); |
+ if (scoped.isLost()) |
+ return; |
+ |
+ if (target != GL_TIME_ELAPSED_EXT) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_ENUM); |
+ return; |
+ } |
+ |
+ if (!m_currentElapsedQuery) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_OPERATION); |
+ return; |
+ } |
+ |
+ scoped.context()->webContext()->endQueryEXT(target); |
+ m_currentElapsedQuery.clear(); |
+} |
+ |
+void EXTDisjointTimerQuery::queryCounterEXT(WebGLTimerQueryEXT* query, GLenum target) |
+{ |
+ WebGLExtensionScopedContext scoped(this); |
+ if (scoped.isLost()) |
+ return; |
+ |
+ if (!query || query->isDeleted() || !query->validate(0, scoped.context())) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_OPERATION); |
+ return; |
+ } |
+ |
+ if (target != GL_TIMESTAMP_EXT) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_ENUM); |
+ return; |
+ } |
+ |
+ if (query->hasTarget() && query->target() != target) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_OPERATION); |
+ return; |
+ } |
+ |
+ scoped.context()->webContext()->queryCounterEXT(query->object(), target); |
+ query->setTarget(target); |
+} |
+ |
+ScriptValue EXTDisjointTimerQuery::getQueryEXT(ScriptState* scriptState, GLenum target, GLenum pname) |
+{ |
+ WebGLExtensionScopedContext scoped(this); |
+ if (scoped.isLost()) |
+ return ScriptValue::createNull(scriptState); |
+ |
+ if (target == GL_TIMESTAMP_EXT || target == GL_TIME_ELAPSED_EXT) { |
+ switch (pname) { |
+ case GL_CURRENT_QUERY_EXT: |
+ if (GL_TIME_ELAPSED_EXT == target && m_currentElapsedQuery.get()) |
+ return WebGLAny(scriptState, m_currentElapsedQuery.get()); |
+ return ScriptValue::createNull(scriptState); |
+ case GL_QUERY_COUNTER_BITS_EXT: { |
+ GLint value = 0; |
+ scoped.context()->webContext()->getQueryivEXT(target, pname, &value); |
+ return WebGLAny(scriptState, value); |
+ } |
+ default: |
+ break; |
+ } |
+ } |
+ |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_ENUM); |
+ return ScriptValue::createNull(scriptState); |
+} |
+ |
+ScriptValue EXTDisjointTimerQuery::getQueryObjectEXT(ScriptState* scriptState, WebGLTimerQueryEXT* query, GLenum pname) |
+{ |
+ WebGLExtensionScopedContext scoped(this); |
+ if (scoped.isLost()) |
+ return ScriptValue::createNull(scriptState); |
+ |
+ if (!query || query->isDeleted() || !query->validate(0, scoped.context())) { |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_OPERATION); |
+ return ScriptValue::createNull(scriptState); |
+ } |
+ |
+ // TODO(kbr): Per the spec, figure out a way to only update this value once |
+ // the current frame has completed rendering. |
+ switch (pname) { |
+ case GL_QUERY_RESULT_EXT: { |
+ GLuint64 result = 0; |
+ scoped.context()->webContext()->getQueryObjectui64vEXT(query->object(), pname, &result); |
+ return WebGLAny(scriptState, result); |
+ } |
+ case GL_QUERY_RESULT_AVAILABLE_EXT: { |
+ GLuint available = 0; |
+ scoped.context()->webContext()->getQueryObjectuivEXT(query->object(), pname, &available); |
+ return WebGLAny(scriptState, !!available); |
+ } |
+ default: |
+ scoped.context()->webContext()->synthesizeGLError(GL_INVALID_ENUM); |
+ break; |
+ } |
+ |
+ return ScriptValue::createNull(scriptState); |
+} |
+ |
+DEFINE_TRACE(EXTDisjointTimerQuery) |
+{ |
+ visitor->trace(m_currentElapsedQuery); |
+ WebGLExtension::trace(visitor); |
+} |
+ |
+EXTDisjointTimerQuery::EXTDisjointTimerQuery(WebGLRenderingContextBase* context) |
+ : WebGLExtension(context) |
+{ |
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_disjoint_timer_query"); |
+} |
+ |
+} // namespace blink |