// 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 "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->resetCachedResult(); 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); query->resetCachedResult(); } 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()) || m_currentElapsedQuery == query) { scoped.context()->webContext()->synthesizeGLError(GL_INVALID_OPERATION); return ScriptValue::createNull(scriptState); } switch (pname) { case GL_QUERY_RESULT_EXT: { query->updateCachedResult(scoped.context()->webContext()); return WebGLAny(scriptState, query->getQueryResult()); } case GL_QUERY_RESULT_AVAILABLE_EXT: { query->updateCachedResult(scoped.context()->webContext()); return WebGLAny(scriptState, query->isQueryResultAvailable()); } 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