2018-11-30 22:52:05 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2014-09-18 02:08:41 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "WebGL2Context.h"
|
|
|
|
#include "GLContext.h"
|
2014-11-03 08:35:04 +03:00
|
|
|
#include "WebGLQuery.h"
|
2015-12-19 01:05:42 +03:00
|
|
|
#include "gfxPrefs.h"
|
|
|
|
#include "nsThreadUtils.h"
|
2014-09-18 02:08:41 +04:00
|
|
|
|
2015-04-17 04:17:07 +03:00
|
|
|
namespace mozilla {
|
2014-09-18 02:08:41 +04:00
|
|
|
|
2014-11-03 08:35:04 +03:00
|
|
|
/*
|
|
|
|
* We fake ANY_SAMPLES_PASSED and ANY_SAMPLES_PASSED_CONSERVATIVE with
|
|
|
|
* SAMPLES_PASSED on desktop.
|
|
|
|
*
|
2014-11-14 07:03:50 +03:00
|
|
|
* OpenGL ES 3.0 spec 4.1.6:
|
|
|
|
* If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE, an
|
|
|
|
* implementation may choose to use a less precise version of the test which
|
|
|
|
* can additionally set the samples-boolean state to TRUE in some other
|
|
|
|
* implementation-dependent cases.
|
2014-11-03 08:35:04 +03:00
|
|
|
*/
|
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
WebGLRefPtr<WebGLQuery>* WebGLContext::ValidateQuerySlotByTarget(
|
|
|
|
GLenum target) {
|
2016-10-04 04:33:52 +03:00
|
|
|
if (IsWebGL2()) {
|
|
|
|
switch (target) {
|
|
|
|
case LOCAL_GL_ANY_SAMPLES_PASSED:
|
|
|
|
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
|
|
|
|
return &mQuerySlot_SamplesPassed;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
|
|
|
|
return &mQuerySlot_TFPrimsWritten;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
default:
|
|
|
|
break;
|
2014-11-03 08:35:04 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) {
|
|
|
|
switch (target) {
|
|
|
|
case LOCAL_GL_TIME_ELAPSED_EXT:
|
|
|
|
return &mQuerySlot_TimeElapsed;
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
default:
|
|
|
|
break;
|
2015-04-17 04:17:07 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2016-10-04 04:33:52 +03:00
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
ErrorInvalidEnumInfo("target", target);
|
2016-10-04 04:33:52 +03:00
|
|
|
return nullptr;
|
2014-11-03 08:35:04 +03:00
|
|
|
}
|
|
|
|
|
2014-09-18 02:08:41 +04:00
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
// Query Objects
|
|
|
|
|
2014-11-03 08:35:04 +03:00
|
|
|
already_AddRefed<WebGLQuery> WebGLContext::CreateQuery() {
|
2018-07-27 07:46:33 +03:00
|
|
|
const FuncScope funcScope(*this, "createQuery");
|
2014-11-03 08:35:04 +03:00
|
|
|
if (IsContextLost()) return nullptr;
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<WebGLQuery> globj = new WebGLQuery(this);
|
2014-11-03 08:35:04 +03:00
|
|
|
return globj.forget();
|
|
|
|
}
|
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
void WebGLContext::DeleteQuery(WebGLQuery* query) {
|
|
|
|
const FuncScope funcScope(*this, "deleteQuery");
|
|
|
|
if (!ValidateDeleteObject(query)) return;
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
query->DeleteQuery();
|
2014-11-03 08:35:04 +03:00
|
|
|
}
|
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
void WebGLContext::BeginQuery(GLenum target, WebGLQuery& query) {
|
|
|
|
const FuncScope funcScope(*this, "beginQuery");
|
2014-11-03 08:35:04 +03:00
|
|
|
if (IsContextLost()) return;
|
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
if (!ValidateObject("query", query)) return;
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
const auto& slot = ValidateQuerySlotByTarget(target);
|
2016-10-04 04:33:52 +03:00
|
|
|
if (!slot) return;
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
if (*slot) return ErrorInvalidOperation("Query target already active.");
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
////
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-11-02 00:58:07 +03:00
|
|
|
query.BeginQuery(target, *slot);
|
2016-01-07 22:05:00 +03:00
|
|
|
}
|
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
void WebGLContext::EndQuery(GLenum target) {
|
|
|
|
const FuncScope funcScope(*this, "endQuery");
|
2014-11-03 08:35:04 +03:00
|
|
|
if (IsContextLost()) return;
|
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
const auto& slot = ValidateQuerySlotByTarget(target);
|
2016-10-04 04:33:52 +03:00
|
|
|
if (!slot) return;
|
2016-01-07 22:05:00 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
const auto& query = *slot;
|
2018-07-27 07:46:33 +03:00
|
|
|
if (!query) return ErrorInvalidOperation("Query target not active.");
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
query->EndQuery();
|
|
|
|
}
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
void WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
|
2018-07-27 07:46:33 +03:00
|
|
|
JS::MutableHandleValue retval) {
|
|
|
|
const FuncScope funcScope(*this, "getQuery");
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
retval.setNull();
|
|
|
|
if (IsContextLost()) return;
|
2015-12-19 01:05:42 +03:00
|
|
|
|
2014-11-03 08:35:04 +03:00
|
|
|
switch (pname) {
|
2016-10-04 04:33:52 +03:00
|
|
|
case LOCAL_GL_CURRENT_QUERY_EXT: {
|
2016-11-08 06:35:47 +03:00
|
|
|
if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query) &&
|
|
|
|
target == LOCAL_GL_TIMESTAMP) {
|
|
|
|
// Doesn't seem illegal to ask about, but is always null.
|
2018-07-27 07:46:33 +03:00
|
|
|
// TIMESTAMP has no slot, so ValidateQuerySlotByTarget would generate
|
2016-10-04 04:33:52 +03:00
|
|
|
// INVALID_ENUM.
|
2014-11-03 08:35:04 +03:00
|
|
|
return;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2016-11-08 06:35:47 +03:00
|
|
|
const auto& slot = ValidateQuerySlotByTarget(target);
|
2016-10-04 04:33:52 +03:00
|
|
|
if (!slot || !*slot) return;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-11-08 06:37:06 +03:00
|
|
|
const auto& query = *slot;
|
|
|
|
if (target != query->Target()) return;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
JS::Rooted<JS::Value> v(cx);
|
|
|
|
dom::GetOrCreateDOMReflector(cx, slot->get(), &v);
|
|
|
|
retval.set(v);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
return;
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
case LOCAL_GL_QUERY_COUNTER_BITS_EXT:
|
|
|
|
if (!IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query))
|
|
|
|
break;
|
2014-11-03 08:35:04 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
if (target != LOCAL_GL_TIME_ELAPSED_EXT &&
|
|
|
|
target != LOCAL_GL_TIMESTAMP_EXT) {
|
|
|
|
ErrorInvalidEnumInfo("target", target);
|
2018-11-30 13:46:48 +03:00
|
|
|
return;
|
|
|
|
}
|
2016-10-04 04:33:52 +03:00
|
|
|
|
2018-11-30 13:46:48 +03:00
|
|
|
{
|
2016-10-04 04:33:52 +03:00
|
|
|
GLint bits = 0;
|
|
|
|
gl->fGetQueryiv(target, pname, &bits);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-10-04 04:33:52 +03:00
|
|
|
if (!Has64BitTimestamps() && bits > 32) {
|
|
|
|
bits = 32;
|
|
|
|
}
|
|
|
|
retval.set(JS::Int32Value(bits));
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2014-11-03 08:35:04 +03:00
|
|
|
return;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
ErrorInvalidEnumInfo("pname", pname);
|
2014-09-18 02:08:41 +04:00
|
|
|
}
|
2015-04-17 04:17:07 +03:00
|
|
|
|
2016-11-02 00:58:07 +03:00
|
|
|
void WebGLContext::GetQueryParameter(JSContext*, const WebGLQuery& query,
|
|
|
|
GLenum pname,
|
2018-07-27 07:46:33 +03:00
|
|
|
JS::MutableHandleValue retval) {
|
|
|
|
const FuncScope funcScope(*this, "getQueryParameter");
|
2016-10-04 04:33:52 +03:00
|
|
|
retval.setNull();
|
|
|
|
if (IsContextLost()) return;
|
2015-04-17 04:17:07 +03:00
|
|
|
|
2018-07-27 07:46:33 +03:00
|
|
|
if (!ValidateObject("query", query)) return;
|
2016-10-04 04:33:52 +03:00
|
|
|
|
2016-11-02 00:58:07 +03:00
|
|
|
query.GetQueryParameter(pname, retval);
|
2015-04-17 04:17:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace mozilla
|