blob: 647d359d89f3d2d8b0852997ecf40a3996433f1c [file] [log] [blame]
// 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 "gpu/command_buffer/client/gles2_interface.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()->contextGL());
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()->contextGL()->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()->synthesizeGLError(GL_INVALID_OPERATION, "beginQueryEXT",
"invalid query");
return;
}
if (target != GL_TIME_ELAPSED_EXT) {
scoped.context()->synthesizeGLError(GL_INVALID_ENUM, "beginQueryEXT",
"invalid target");
return;
}
if (m_currentElapsedQuery) {
scoped.context()->synthesizeGLError(GL_INVALID_OPERATION, "beginQueryEXT",
"no current query");
return;
}
if (query->hasTarget() && query->target() != target) {
scoped.context()->synthesizeGLError(GL_INVALID_OPERATION, "beginQueryEXT",
"target does not match query");
return;
}
scoped.context()->contextGL()->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()->synthesizeGLError(GL_INVALID_ENUM, "endQueryEXT",
"invalid target");
return;
}
if (!m_currentElapsedQuery) {
scoped.context()->synthesizeGLError(GL_INVALID_OPERATION, "endQueryEXT",
"no current query");
return;
}
scoped.context()->contextGL()->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()->synthesizeGLError(GL_INVALID_OPERATION, "queryCounterEXT",
"invalid query");
return;
}
if (target != GL_TIMESTAMP_EXT) {
scoped.context()->synthesizeGLError(GL_INVALID_ENUM, "queryCounterEXT",
"invalid target");
return;
}
if (query->hasTarget() && query->target() != target) {
scoped.context()->synthesizeGLError(GL_INVALID_OPERATION, "queryCounterEXT",
"target does not match query");
return;
}
// Timestamps are disabled in WebGL due to lack of driver support on multiple
// platforms, so we don't actually perform a GL call.
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()->contextGL()->GetQueryivEXT(target, pname, &value);
return WebGLAny(scriptState, value);
}
default:
break;
}
}
scoped.context()->synthesizeGLError(GL_INVALID_ENUM, "getQueryEXT",
"invalid target or pname");
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()->synthesizeGLError(GL_INVALID_OPERATION,
"getQueryObjectEXT", "invalid query");
return ScriptValue::createNull(scriptState);
}
switch (pname) {
case GL_QUERY_RESULT_EXT: {
query->updateCachedResult(scoped.context()->contextGL());
return WebGLAny(scriptState, query->getQueryResult());
}
case GL_QUERY_RESULT_AVAILABLE_EXT: {
query->updateCachedResult(scoped.context()->contextGL());
return WebGLAny(scriptState, query->isQueryResultAvailable());
}
default:
scoped.context()->synthesizeGLError(GL_INVALID_ENUM, "getQueryObjectEXT",
"invalid pname");
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