1 /* -*- Mode: C++; tab-width: 20; 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 "WebGLQuery.h"
9 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
10 #include "mozilla/StaticPrefs_webgl.h"
11 #include "nsContentUtils.h"
12 #include "WebGLContext.h"
18 static GLuint
GenQuery(gl::GLContext
* gl
) {
20 gl
->fGenQueries(1, &ret
);
24 WebGLQuery::WebGLQuery(WebGLContext
* webgl
)
25 : WebGLContextBoundObject(webgl
),
26 mGLName(GenQuery(mContext
->gl
)),
28 mActiveSlot(nullptr) {}
30 WebGLQuery::~WebGLQuery() {
31 if (!mContext
) return;
32 mContext
->gl
->fDeleteQueries(1, &mGLName
);
37 static GLenum
TargetForDriver(const gl::GLContext
* gl
, GLenum target
) {
39 case LOCAL_GL_ANY_SAMPLES_PASSED
:
40 case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE
:
47 if (gl
->IsSupported(gl::GLFeature::occlusion_query_boolean
)) return target
;
49 if (gl
->IsSupported(gl::GLFeature::occlusion_query2
))
50 return LOCAL_GL_ANY_SAMPLES_PASSED
;
52 return LOCAL_GL_SAMPLES_PASSED
;
55 void WebGLQuery::BeginQuery(GLenum target
, RefPtr
<WebGLQuery
>& slot
) {
62 const auto& gl
= mContext
->gl
;
64 const auto driverTarget
= TargetForDriver(gl
, mTarget
);
65 gl
->fBeginQuery(driverTarget
, mGLName
);
68 void WebGLQuery::EndQuery() {
69 *mActiveSlot
= nullptr;
70 mActiveSlot
= nullptr;
71 mCanBeAvailable
= false;
75 const auto& gl
= mContext
->gl
;
77 const auto driverTarget
= TargetForDriver(gl
, mTarget
);
78 gl
->fEndQuery(driverTarget
);
81 Maybe
<double> WebGLQuery::GetQueryParameter(GLenum pname
) const {
83 case LOCAL_GL_QUERY_RESULT_AVAILABLE
:
84 case LOCAL_GL_QUERY_RESULT
:
88 mContext
->ErrorInvalidEnumInfo("pname", pname
);
93 mContext
->ErrorInvalidOperation("Query has never been active.");
98 mContext
->ErrorInvalidOperation("Query is still active.");
105 const auto& gl
= mContext
->gl
;
109 case LOCAL_GL_QUERY_RESULT_AVAILABLE
:
110 gl
->fGetQueryObjectuiv(mGLName
, pname
, (GLuint
*)&val
);
111 return Some(static_cast<bool>(val
));
113 case LOCAL_GL_QUERY_RESULT
:
115 case LOCAL_GL_TIME_ELAPSED_EXT
:
116 case LOCAL_GL_TIMESTAMP_EXT
:
117 if (mContext
->Has64BitTimestamps()) {
118 gl
->fGetQueryObjectui64v(mGLName
, pname
, &val
);
124 gl
->fGetQueryObjectuiv(mGLName
, LOCAL_GL_QUERY_RESULT
, (GLuint
*)&val
);
129 case LOCAL_GL_ANY_SAMPLES_PASSED
:
130 case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE
:
131 case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
:
132 case LOCAL_GL_TIME_ELAPSED_EXT
:
133 case LOCAL_GL_TIMESTAMP_EXT
:
136 MOZ_CRASH("Bad `mTarget`.");
139 MOZ_CRASH("Bad `pname`.");
143 void WebGLQuery::QueryCounter() {
144 const GLenum target
= LOCAL_GL_TIMESTAMP_EXT
;
145 if (mTarget
&& target
!= mTarget
) {
146 mContext
->ErrorInvalidOperation("Queries cannot change targets.");
151 mCanBeAvailable
= false;
153 const auto& gl
= mContext
->gl
;
154 gl
->fQueryCounter(mGLName
, mTarget
);
157 } // namespace mozilla