1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "WebGL2Context.h"
8 #include "WebGLQuery.h"
10 #include "nsThreadUtils.h"
15 * We fake ANY_SAMPLES_PASSED and ANY_SAMPLES_PASSED_CONSERVATIVE with
16 * SAMPLES_PASSED on desktop.
18 * OpenGL ES 3.0 spec 4.1.6:
19 * If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE, an
20 * implementation may choose to use a less precise version of the test which
21 * can additionally set the samples-boolean state to TRUE in some other
22 * implementation-dependent cases.
25 WebGLRefPtr
<WebGLQuery
>* WebGLContext::ValidateQuerySlotByTarget(
29 case LOCAL_GL_ANY_SAMPLES_PASSED
:
30 case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE
:
31 return &mQuerySlot_SamplesPassed
;
33 case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
:
34 return &mQuerySlot_TFPrimsWritten
;
41 if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query
)) {
43 case LOCAL_GL_TIME_ELAPSED_EXT
:
44 return &mQuerySlot_TimeElapsed
;
51 ErrorInvalidEnumInfo("target", target
);
55 // -------------------------------------------------------------------------
58 already_AddRefed
<WebGLQuery
> WebGLContext::CreateQuery() {
59 const FuncScope
funcScope(*this, "createQuery");
60 if (IsContextLost()) return nullptr;
62 RefPtr
<WebGLQuery
> globj
= new WebGLQuery(this);
63 return globj
.forget();
66 void WebGLContext::DeleteQuery(WebGLQuery
* query
) {
67 const FuncScope
funcScope(*this, "deleteQuery");
68 if (!ValidateDeleteObject(query
)) return;
73 void WebGLContext::BeginQuery(GLenum target
, WebGLQuery
& query
) {
74 const FuncScope
funcScope(*this, "beginQuery");
75 if (IsContextLost()) return;
77 if (!ValidateObject("query", query
)) return;
79 const auto& slot
= ValidateQuerySlotByTarget(target
);
82 if (*slot
) return ErrorInvalidOperation("Query target already active.");
86 query
.BeginQuery(target
, *slot
);
89 void WebGLContext::EndQuery(GLenum target
) {
90 const FuncScope
funcScope(*this, "endQuery");
91 if (IsContextLost()) return;
93 const auto& slot
= ValidateQuerySlotByTarget(target
);
96 const auto& query
= *slot
;
97 if (!query
) return ErrorInvalidOperation("Query target not active.");
102 void WebGLContext::GetQuery(JSContext
* cx
, GLenum target
, GLenum pname
,
103 JS::MutableHandleValue retval
) {
104 const FuncScope
funcScope(*this, "getQuery");
107 if (IsContextLost()) return;
110 case LOCAL_GL_CURRENT_QUERY_EXT
: {
111 if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query
) &&
112 target
== LOCAL_GL_TIMESTAMP
) {
113 // Doesn't seem illegal to ask about, but is always null.
114 // TIMESTAMP has no slot, so ValidateQuerySlotByTarget would generate
119 const auto& slot
= ValidateQuerySlotByTarget(target
);
120 if (!slot
|| !*slot
) return;
122 const auto& query
= *slot
;
123 if (target
!= query
->Target()) return;
125 JS::Rooted
<JS::Value
> v(cx
);
126 dom::GetOrCreateDOMReflector(cx
, slot
->get(), &v
);
131 case LOCAL_GL_QUERY_COUNTER_BITS_EXT
:
132 if (!IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query
))
135 if (target
!= LOCAL_GL_TIME_ELAPSED_EXT
&&
136 target
!= LOCAL_GL_TIMESTAMP_EXT
) {
137 ErrorInvalidEnumInfo("target", target
);
143 gl
->fGetQueryiv(target
, pname
, &bits
);
145 if (!Has64BitTimestamps() && bits
> 32) {
148 retval
.set(JS::Int32Value(bits
));
156 ErrorInvalidEnumInfo("pname", pname
);
159 void WebGLContext::GetQueryParameter(JSContext
*, const WebGLQuery
& query
,
161 JS::MutableHandleValue retval
) {
162 const FuncScope
funcScope(*this, "getQueryParameter");
164 if (IsContextLost()) return;
166 if (!ValidateObject("query", query
)) return;
168 query
.GetQueryParameter(pname
, retval
);
171 } // namespace mozilla