Bug 1308057 - Merge WebGLTimerQuery into WebGLQuery. - r=ethlin

MozReview-Commit-ID: 88b8DLd2uJ6
This commit is contained in:
Jeff Gilbert (:jgilbert) 2016-10-03 18:33:52 -07:00
parent bd6c33a960
commit b054199751
16 changed files with 488 additions and 732 deletions

View File

@ -38,12 +38,6 @@ WebGL1Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
return dom::WebGLRenderingContextBinding::Wrap(cx, this, givenProto);
}
bool
WebGL1Context::ValidateQueryTarget(GLenum target, const char* info)
{
return false;
}
} // namespace mozilla
nsresult

View File

@ -36,7 +36,6 @@ private:
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type,
uint32_t* alignment,
const char* info) override;
virtual bool ValidateQueryTarget(GLenum target, const char* info) override;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override;
};

View File

@ -302,18 +302,6 @@ public:
void ClearBufferfi(GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil);
// -------------------------------------------------------------------------
// Query Objects - WebGL2ContextQueries.cpp
already_AddRefed<WebGLQuery> CreateQuery();
void DeleteQuery(WebGLQuery* query);
bool IsQuery(WebGLQuery* query);
void BeginQuery(GLenum target, WebGLQuery* query);
void EndQuery(GLenum target);
already_AddRefed<WebGLQuery> GetQuery(GLenum target, GLenum pname);
void GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname, JS::MutableHandleValue retval);
// -------------------------------------------------------------------------
// Sampler Objects - WebGL2ContextSamplers.cpp
@ -410,7 +398,6 @@ private:
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type,
uint32_t* alignment,
const char* info) override;
virtual bool ValidateQueryTarget(GLenum target, const char* info) override;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override;
};

View File

@ -22,58 +22,35 @@ namespace mozilla {
* implementation-dependent cases.
*/
static const char*
GetQueryTargetEnumString(GLenum target)
WebGLRefPtr<WebGLQuery>*
WebGLContext::ValidateQuerySlotByTarget(const char* funcName, GLenum target)
{
switch (target)
{
case LOCAL_GL_ANY_SAMPLES_PASSED:
return "ANY_SAMPLES_PASSED";
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
return "ANY_SAMPLES_PASSED_CONSERVATIVE";
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN";
default:
break;
if (IsWebGL2()) {
switch (target) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
return &mQuerySlot_SamplesPassed;
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return &mQuerySlot_TFPrimsWritten;
default:
break;
}
}
MOZ_ASSERT(false, "Unknown query `target`.");
return "UNKNOWN_QUERY_TARGET";
}
if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) {
switch (target) {
case LOCAL_GL_TIME_ELAPSED_EXT:
return &mQuerySlot_TimeElapsed;
static inline GLenum
SimulateOcclusionQueryTarget(const gl::GLContext* gl, GLenum target)
{
MOZ_ASSERT(target == LOCAL_GL_ANY_SAMPLES_PASSED ||
target == LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE,
"unknown occlusion query target");
if (gl->IsSupported(gl::GLFeature::occlusion_query_boolean)) {
return target;
} else if (gl->IsSupported(gl::GLFeature::occlusion_query2)) {
return LOCAL_GL_ANY_SAMPLES_PASSED;
default:
break;
}
}
return LOCAL_GL_SAMPLES_PASSED;
}
WebGLRefPtr<WebGLQuery>&
WebGLContext::GetQuerySlotByTarget(GLenum target)
{
/* This function assumes that target has been validated for either
* WebGL1 or WebGL2.
*/
switch (target) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
return mActiveOcclusionQuery;
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return mActiveTransformFeedbackQuery;
default:
MOZ_CRASH("GFX: Should not get here.");
}
ErrorInvalidEnum("%s: Bad `target`.", funcName);
return nullptr;
}
@ -81,329 +58,179 @@ WebGLContext::GetQuerySlotByTarget(GLenum target)
// Query Objects
already_AddRefed<WebGLQuery>
WebGL2Context::CreateQuery()
WebGLContext::CreateQuery(const char* funcName)
{
if (!funcName) {
funcName = "createQuery";
}
if (IsContextLost())
return nullptr;
if (mActiveOcclusionQuery && !gl->IsGLES()) {
/* http://www.opengl.org/registry/specs/ARB/occlusion_query.txt
*
* Calling either GenQueriesARB or DeleteQueriesARB while any query of
* any target is active causes an INVALID_OPERATION error to be
* generated.
*/
GenerateWarning("createQuery: The WebGL 2 prototype might generate"
" INVALID_OPERATION when creating a query object while"
" one other is active.");
/*
* We *need* to lock webgl2 to GL>=3.0 on desktop, but we don't have a
* good mechanism to do this yet. See bug 898404.
*/
}
RefPtr<WebGLQuery> globj = new WebGLQuery(this);
return globj.forget();
}
void
WebGL2Context::DeleteQuery(WebGLQuery* query)
WebGLContext::DeleteQuery(WebGLQuery* query, const char* funcName)
{
if (!funcName) {
funcName = "deleteQuery";
}
if (IsContextLost())
return;
if (!query)
return;
if (query->IsDeleted())
if (!ValidateObjectAllowDeleted(funcName, query))
return;
if (query->IsActive())
EndQuery(query->mType);
if (mActiveOcclusionQuery && !gl->IsGLES()) {
/* http://www.opengl.org/registry/specs/ARB/occlusion_query.txt
*
* Calling either GenQueriesARB or DeleteQueriesARB while any query of
* any target is active causes an INVALID_OPERATION error to be
* generated.
*/
GenerateWarning("deleteQuery: The WebGL 2 prototype might generate"
" INVALID_OPERATION when deleting a query object while"
" one other is active.");
}
query->RequestDelete();
query->DeleteQuery();
}
bool
WebGL2Context::IsQuery(WebGLQuery* query)
WebGLContext::IsQuery(const WebGLQuery* query, const char* funcName)
{
if (!funcName) {
funcName = "isQuery";
}
if (IsContextLost())
return false;
if (!query)
return false;
return (ValidateObjectAllowDeleted("isQuery", query) &&
!query->IsDeleted() &&
query->HasEverBeenActive());
}
void
WebGL2Context::BeginQuery(GLenum target, WebGLQuery* query)
{
if (IsContextLost())
return;
if (!ValidateQueryTarget(target, "beginQuery"))
return;
if (!query) {
/* From GLES's EXT_occlusion_query_boolean:
* BeginQueryEXT sets the active query object name for the query
* type given by <target> to <id>. If BeginQueryEXT is called with
* an <id> of zero, if the active query object name for <target> is
* non-zero (for the targets ANY_SAMPLES_PASSED_EXT and
* ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if the active query for
* either target is non-zero), if <id> is the name of an existing
* query object whose type does not match <target>, or if <id> is
* the active query object name for any query type, the error
* INVALID_OPERATION is generated.
*/
ErrorInvalidOperation("beginQuery: Query should not be null.");
return;
}
if (query->IsDeleted()) {
/* From GLES's EXT_occlusion_query_boolean:
* BeginQueryEXT fails and an INVALID_OPERATION error is generated
* if <id> is not a name returned from a previous call to
* GenQueriesEXT, or if such a name has since been deleted with
* DeleteQueriesEXT.
*/
ErrorInvalidOperation("beginQuery: Query has been deleted.");
return;
}
if (query->HasEverBeenActive() &&
query->mType != target)
{
ErrorInvalidOperation("beginQuery: Target doesn't match with the query"
" type.");
return;
}
WebGLRefPtr<WebGLQuery>& querySlot = GetQuerySlotByTarget(target);
WebGLQuery* activeQuery = querySlot.get();
if (activeQuery)
return ErrorInvalidOperation("beginQuery: An other query already active.");
if (!query->HasEverBeenActive())
query->mType = target;
MakeContextCurrent();
if (target == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) {
gl->fBeginQuery(LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
query->mGLName);
} else {
gl->fBeginQuery(SimulateOcclusionQueryTarget(gl, target),
query->mGLName);
}
UpdateBoundQuery(target, query);
}
void
WebGL2Context::EndQuery(GLenum target)
{
if (IsContextLost())
return;
if (!ValidateQueryTarget(target, "endQuery"))
return;
WebGLRefPtr<WebGLQuery>& querySlot = GetQuerySlotByTarget(target);
WebGLQuery* activeQuery = querySlot.get();
if (!activeQuery || target != activeQuery->mType)
{
/* From GLES's EXT_occlusion_query_boolean:
* marks the end of the sequence of commands to be tracked for the
* query type given by <target>. The active query object for
* <target> is updated to indicate that query results are not
* available, and the active query object name for <target> is reset
* to zero. When the commands issued prior to EndQueryEXT have
* completed and a final query result is available, the query object
* active when EndQueryEXT is called is updated by the GL. The query
* object is updated to indicate that the query results are
* available and to contain the query result. If the active query
* object name for <target> is zero when EndQueryEXT is called, the
* error INVALID_OPERATION is generated.
*/
ErrorInvalidOperation("endQuery: There is no active query of type %s.",
GetQueryTargetEnumString(target));
return;
}
MakeContextCurrent();
if (target == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) {
gl->fEndQuery(LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
} else {
gl->fEndQuery(SimulateOcclusionQueryTarget(gl, target));
}
UpdateBoundQuery(target, nullptr);
NS_DispatchToCurrentThread(new WebGLQuery::AvailableRunnable(activeQuery));
}
already_AddRefed<WebGLQuery>
WebGL2Context::GetQuery(GLenum target, GLenum pname)
{
if (IsContextLost())
return nullptr;
if (!ValidateQueryTarget(target, "getQuery"))
return nullptr;
if (pname != LOCAL_GL_CURRENT_QUERY) {
/* OpenGL ES 3.0 spec 6.1.7:
* pname must be CURRENT_QUERY.
*/
ErrorInvalidEnum("getQuery: `pname` must be CURRENT_QUERY.");
return nullptr;
}
WebGLRefPtr<WebGLQuery>& targetSlot = GetQuerySlotByTarget(target);
RefPtr<WebGLQuery> tmp = targetSlot.get();
if (tmp && tmp->mType != target) {
// Query in slot doesn't match target
return nullptr;
}
return tmp.forget();
}
static bool
ValidateQueryEnum(WebGLContext* webgl, GLenum pname, const char* info)
{
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
case LOCAL_GL_QUERY_RESULT:
return true;
default:
webgl->ErrorInvalidEnum("%s: invalid pname: %s", info, webgl->EnumName(pname));
if (!ValidateObjectAllowDeleted("isQuery", query))
return false;
}
return query->IsQuery();
}
void
WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname,
JS::MutableHandleValue retval)
WebGLContext::BeginQuery(GLenum target, WebGLQuery* query, const char* funcName)
{
retval.set(JS::NullValue());
if (!funcName) {
funcName = "beginQuery";
}
if (IsContextLost())
return;
if (!ValidateQueryEnum(this, pname, "getQueryParameter"))
if (!ValidateObject(funcName, query))
return;
if (!query) {
/* OpenGL ES 3.0 spec 6.1.7 (spec getQueryObject 1):
* If id is not the name of a query object, or if the query object
* named by id is currently active, then an INVALID_OPERATION error
* is generated. pname must be QUERY_RESULT or
* QUERY_RESULT_AVAILABLE.
*/
ErrorInvalidOperation("getQueryObject: `query` should not be null.");
const auto& slot = ValidateQuerySlotByTarget(funcName, target);
if (!slot)
return;
if (*slot)
return ErrorInvalidOperation("%s: Query target already active.", funcName);
////
if (!query->BeginQuery(target))
return;
*slot = query;
}
void
WebGLContext::EndQuery(GLenum target, const char* funcName)
{
if (!funcName) {
funcName = "endQuery";
}
if (query->IsDeleted()) {
// See (spec getQueryObject 1)
ErrorInvalidOperation("getQueryObject: `query` has been deleted.");
if (IsContextLost())
return;
const auto& slot = ValidateQuerySlotByTarget(funcName, target);
if (!slot)
return;
const auto& query = *slot;
if (!query)
return ErrorInvalidOperation("%s: Query target not active.", funcName);
query->EndQuery();
*slot = nullptr;
}
void
WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval, const char* funcName)
{
if (!funcName) {
funcName = "getQuery";
}
if (query->IsActive()) {
// See (spec getQueryObject 1)
ErrorInvalidOperation("getQueryObject: `query` is active.");
retval.setNull();
if (IsContextLost())
return;
}
if (!query->HasEverBeenActive()) {
/* See (spec getQueryObject 1)
* If this instance of WebGLQuery has never been active before, that
* mean that query->mGLName is not a query object yet.
*/
ErrorInvalidOperation("getQueryObject: `query` has never been active.");
return;
}
switch (pname) {
case LOCAL_GL_CURRENT_QUERY_EXT:
{
const auto& slot = ValidateQuerySlotByTarget(funcName, target);
if (!slot || !*slot)
return;
// We must wait for an event loop before the query can be available
if (!query->mCanBeAvailable && !gfxPrefs::WebGLImmediateQueries()) {
if (pname == LOCAL_GL_QUERY_RESULT_AVAILABLE) {
retval.set(JS::BooleanValue(false));
JS::Rooted<JS::Value> v(cx);
dom::GetOrCreateDOMReflector(cx, slot->get(), &v);
retval.set(v);
}
return;
}
MakeContextCurrent();
GLuint returned = 0;
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
gl->fGetQueryObjectuiv(query->mGLName, LOCAL_GL_QUERY_RESULT_AVAILABLE, &returned);
retval.set(JS::BooleanValue(returned != 0));
return;
case LOCAL_GL_QUERY_COUNTER_BITS_EXT:
if (!IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query))
break;
case LOCAL_GL_QUERY_RESULT:
gl->fGetQueryObjectuiv(query->mGLName, LOCAL_GL_QUERY_RESULT, &returned);
if (query->mType == LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN) {
retval.set(JS::NumberValue(returned));
if (target != LOCAL_GL_TIME_ELAPSED_EXT &&
target != LOCAL_GL_TIMESTAMP_EXT)
{
ErrorInvalidEnum("%s: Bad pname for target.", funcName);
return;
}
/*
* test (returned != 0) is important because ARB_occlusion_query on desktop drivers
* return the number of samples drawed when the OpenGL ES extension
* ARB_occlusion_query_boolean return only a boolean if a sample has been drawed.
*/
retval.set(JS::BooleanValue(returned != 0));
{
GLint bits = 0;
gl->fGetQueryiv(target, pname, &bits);
if (!Has64BitTimestamps() && bits > 32) {
bits = 32;
}
retval.set(JS::Int32Value(bits));
}
return;
default:
break;
}
ErrorInvalidEnum("getQueryObject: `pname` must be QUERY_RESULT{_AVAILABLE}.");
ErrorInvalidEnum("%s: Bad pname.", funcName);
return;
}
void
WebGL2Context::UpdateBoundQuery(GLenum target, WebGLQuery* query)
WebGLContext::GetQueryParameter(JSContext*, const WebGLQuery* query, GLenum pname,
JS::MutableHandleValue retval, const char* funcName)
{
WebGLRefPtr<WebGLQuery>& querySlot = GetQuerySlotByTarget(target);
querySlot = query;
}
bool
WebGL2Context::ValidateQueryTarget(GLenum target, const char* info)
{
switch (target) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return true;
default:
ErrorInvalidEnumInfo(info, target);
return false;
if (!funcName) {
funcName = "getQueryParameter";
}
retval.setNull();
if (IsContextLost())
return;
if (!ValidateObject(funcName, query))
return;
query->GetQueryParameter(pname, retval);
}
} // namespace mozilla

View File

@ -71,7 +71,6 @@
#include "WebGLSampler.h"
#include "WebGLShader.h"
#include "WebGLSync.h"
#include "WebGLTimerQuery.h"
#include "WebGLTransformFeedback.h"
#include "WebGLVertexArray.h"
#include "WebGLVertexAttribData.h"
@ -252,13 +251,16 @@ WebGLContext::DestroyResourcesAndContext()
mActiveProgramLinkInfo = nullptr;
mBoundDrawFramebuffer = nullptr;
mBoundReadFramebuffer = nullptr;
mActiveOcclusionQuery = nullptr;
mBoundRenderbuffer = nullptr;
mBoundVertexArray = nullptr;
mDefaultVertexArray = nullptr;
mBoundTransformFeedback = nullptr;
mDefaultTransformFeedback = nullptr;
mQuerySlot_SamplesPassed = nullptr;
mQuerySlot_TFPrimsWritten = nullptr;
mQuerySlot_TimeElapsed = nullptr;
mIndexedUniformBufferBindings.clear();
//////
@ -272,7 +274,6 @@ WebGLContext::DestroyResourcesAndContext()
ClearLinkedList(mShaders);
ClearLinkedList(mSyncs);
ClearLinkedList(mTextures);
ClearLinkedList(mTimerQueries);
ClearLinkedList(mTransformFeedbacks);
ClearLinkedList(mVertexArrays);
@ -1647,7 +1648,7 @@ WebGLContext::DummyReadFramebufferOperation(const char* funcName)
}
bool
WebGLContext::HasTimestampBits() const
WebGLContext::Has64BitTimestamps() const
{
// 'sync' provides glGetInteger64v either by supporting ARB_sync, GL3+, or GLES3+.
return gl->IsSupported(GLFeature::sync);
@ -2601,8 +2602,9 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLContext,
mBoundRenderbuffer,
mBoundVertexArray,
mDefaultVertexArray,
mActiveOcclusionQuery,
mActiveTransformFeedbackQuery)
mQuerySlot_SamplesPassed,
mQuerySlot_TFPrimsWritten,
mQuerySlot_TimeElapsed)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY

View File

@ -103,7 +103,6 @@ class WebGLShader;
class WebGLShaderPrecisionFormat;
class WebGLSync;
class WebGLTexture;
class WebGLTimerQuery;
class WebGLTransformFeedback;
class WebGLUniformLocation;
class WebGLVertexArray;
@ -446,7 +445,7 @@ public:
// a number that increments every time we have an event that causes
// all context resources to be lost.
uint32_t Generation() { return mGeneration.value(); }
uint32_t Generation() const { return mGeneration.value(); }
// This is similar to GLContext::ClearSafely, but tries to minimize the
// amount of work it does.
@ -934,10 +933,24 @@ protected:
// -----------------------------------------------------------------------------
// Queries (WebGL2ContextQueries.cpp)
protected:
WebGLRefPtr<WebGLQuery>& GetQuerySlotByTarget(GLenum target);
WebGLRefPtr<WebGLQuery> mQuerySlot_SamplesPassed;
WebGLRefPtr<WebGLQuery> mQuerySlot_TFPrimsWritten;
WebGLRefPtr<WebGLQuery> mQuerySlot_TimeElapsed;
WebGLRefPtr<WebGLQuery>*
ValidateQuerySlotByTarget(const char* funcName, GLenum target);
public:
already_AddRefed<WebGLQuery> CreateQuery(const char* funcName = nullptr);
void DeleteQuery(WebGLQuery* query, const char* funcName = nullptr);
bool IsQuery(const WebGLQuery* query, const char* funcName = nullptr);
void BeginQuery(GLenum target, WebGLQuery* query, const char* funcName = nullptr);
void EndQuery(GLenum target, const char* funcName = nullptr);
void GetQuery(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval, const char* funcName = nullptr);
void GetQueryParameter(JSContext* cx, const WebGLQuery* query, GLenum pname,
JS::MutableHandleValue retval, const char* funcName = nullptr);
WebGLRefPtr<WebGLQuery> mActiveOcclusionQuery;
WebGLRefPtr<WebGLQuery> mActiveTransformFeedbackQuery;
// -----------------------------------------------------------------------------
// State and State Requests (WebGLContextState.cpp)
@ -1610,27 +1623,27 @@ protected:
// Returns false if `object` is null or not valid.
template<class ObjectType>
bool ValidateObject(const char* info, ObjectType* object);
bool ValidateObject(const char* info, const ObjectType* object);
// Returns false if `object` is not valid. Considers null to be valid.
template<class ObjectType>
bool ValidateObjectAllowNull(const char* info, ObjectType* object);
bool ValidateObjectAllowNull(const char* info, const ObjectType* object);
// Returns false if `object` is not valid, but considers deleted objects and
// null objects valid.
template<class ObjectType>
bool ValidateObjectAllowDeletedOrNull(const char* info, ObjectType* object);
bool ValidateObjectAllowDeletedOrNull(const char* info, const ObjectType* object);
// Returns false if `object` is null or not valid, but considers deleted
// objects valid.
template<class ObjectType>
bool ValidateObjectAllowDeleted(const char* info, ObjectType* object);
bool ValidateObjectAllowDeleted(const char* info, const ObjectType* object);
private:
// Like ValidateObject, but only for cases when `object` is known to not be
// null already.
template<class ObjectType>
bool ValidateObjectAssumeNonNull(const char* info, ObjectType* object);
bool ValidateObjectAssumeNonNull(const char* info, const ObjectType* object);
private:
// -------------------------------------------------------------------------
@ -1638,7 +1651,6 @@ private:
virtual WebGLVertexArray* CreateVertexArrayImpl();
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, uint32_t* alignment, const char* info) = 0;
virtual bool ValidateQueryTarget(GLenum usage, const char* info) = 0;
virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) = 0;
public:
@ -1675,7 +1687,6 @@ protected:
LinkedList<WebGLShader> mShaders;
LinkedList<WebGLSync> mSyncs;
LinkedList<WebGLTexture> mTextures;
LinkedList<WebGLTimerQuery> mTimerQueries;
LinkedList<WebGLTransformFeedback> mTransformFeedbacks;
LinkedList<WebGLVertexArray> mVertexArrays;
@ -1790,7 +1801,7 @@ protected:
bool mNeedsFakeNoStencil;
bool mNeedsEmulatedLoneDepthStencil;
bool HasTimestampBits() const;
bool Has64BitTimestamps() const;
struct ScopedMaskWorkaround {
WebGLContext& mWebGL;
@ -1898,7 +1909,6 @@ public:
friend class WebGLSampler;
friend class WebGLShader;
friend class WebGLSync;
friend class WebGLTimerQuery;
friend class WebGLTransformFeedback;
friend class WebGLUniformLocation;
friend class WebGLVertexArray;
@ -1920,7 +1930,7 @@ ToSupports(WebGLContext* webgl)
template<class ObjectType>
inline bool
WebGLContext::ValidateObjectAllowDeletedOrNull(const char* info,
ObjectType* object)
const ObjectType* object)
{
if (object && !object->IsCompatibleWithContext(this)) {
ErrorInvalidOperation("%s: object from different WebGL context "
@ -1934,7 +1944,7 @@ WebGLContext::ValidateObjectAllowDeletedOrNull(const char* info,
template<class ObjectType>
inline bool
WebGLContext::ValidateObjectAssumeNonNull(const char* info, ObjectType* object)
WebGLContext::ValidateObjectAssumeNonNull(const char* info, const ObjectType* object)
{
MOZ_ASSERT(object);
@ -1951,7 +1961,7 @@ WebGLContext::ValidateObjectAssumeNonNull(const char* info, ObjectType* object)
template<class ObjectType>
inline bool
WebGLContext::ValidateObjectAllowNull(const char* info, ObjectType* object)
WebGLContext::ValidateObjectAllowNull(const char* info, const ObjectType* object)
{
if (!object)
return true;
@ -1961,7 +1971,7 @@ WebGLContext::ValidateObjectAllowNull(const char* info, ObjectType* object)
template<class ObjectType>
inline bool
WebGLContext::ValidateObjectAllowDeleted(const char* info, ObjectType* object)
WebGLContext::ValidateObjectAllowDeleted(const char* info, const ObjectType* object)
{
if (!object) {
ErrorInvalidValue("%s: null object passed as argument", info);
@ -1973,7 +1983,7 @@ WebGLContext::ValidateObjectAllowDeleted(const char* info, ObjectType* object)
template<class ObjectType>
inline bool
WebGLContext::ValidateObject(const char* info, ObjectType* object)
WebGLContext::ValidateObject(const char* info, const ObjectType* object)
{
if (!object) {
ErrorInvalidValue("%s: null object passed as argument", info);

View File

@ -264,24 +264,31 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
}
}
if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) {
if (pname == LOCAL_GL_TIMESTAMP_EXT) {
GLuint64 iv = 0;
if (HasTimestampBits()) {
gl->fGetInteger64v(pname, (GLint64*)&iv);
} else {
GenerateWarning("QUERY_COUNTER_BITS_EXT for TIMESTAMP_EXT is 0.");
if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) {
switch (pname) {
case LOCAL_GL_TIMESTAMP_EXT:
{
uint64_t val = 0;
if (Has64BitTimestamps()) {
gl->fGetInteger64v(pname, (GLint64*)&val);
} else {
gl->fGetIntegerv(pname, (GLint*)&val);
}
// TODO: JS doesn't support 64-bit integers. Be lossy and
// cast to double (53 bits)
return JS::NumberValue(val);
}
// TODO: JS doesn't support 64-bit integers. Be lossy and
// cast to double (53 bits)
return JS::NumberValue(static_cast<double>(iv));
} else if (pname == LOCAL_GL_GPU_DISJOINT_EXT) {
// When disjoint isn't supported, leave as false.
realGLboolean disjoint = LOCAL_GL_FALSE;
if (gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query)) {
gl->fGetBooleanv(pname, &disjoint);
case LOCAL_GL_GPU_DISJOINT_EXT:
{
MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query));
realGLboolean val = false;
gl->fGetBooleanv(pname, &val);
return JS::BooleanValue(val);
}
return JS::BooleanValue(bool(disjoint));
default:
break;
}
}

View File

@ -12,13 +12,12 @@
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "mozilla/dom/BindingUtils.h"
#include "WebGLContext.h"
#include "WebGLTimerQuery.h"
#include "WebGLQuery.h"
namespace mozilla {
WebGLExtensionDisjointTimerQuery::WebGLExtensionDisjointTimerQuery(WebGLContext* webgl)
: WebGLExtensionBase(webgl)
, mActiveQuery(nullptr)
{
MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
}
@ -27,225 +26,92 @@ WebGLExtensionDisjointTimerQuery::~WebGLExtensionDisjointTimerQuery()
{
}
already_AddRefed<WebGLTimerQuery>
WebGLExtensionDisjointTimerQuery::CreateQueryEXT()
already_AddRefed<WebGLQuery>
WebGLExtensionDisjointTimerQuery::CreateQueryEXT() const
{
const char funcName[] = "createQueryEXT";
if (mIsLost)
return nullptr;
RefPtr<WebGLTimerQuery> query = WebGLTimerQuery::Create(mContext);
return query.forget();
return mContext->CreateQuery(funcName);
}
void
WebGLExtensionDisjointTimerQuery::DeleteQueryEXT(WebGLTimerQuery* query)
WebGLExtensionDisjointTimerQuery::DeleteQueryEXT(WebGLQuery* query) const
{
const char funcName[] = "deleteQueryEXT";
if (mIsLost)
return;
if (!mContext->ValidateObject("deleteQueryEXT", query))
return;
query->RequestDelete();
mContext->DeleteQuery(query, funcName);
}
bool
WebGLExtensionDisjointTimerQuery::IsQueryEXT(WebGLTimerQuery* query)
WebGLExtensionDisjointTimerQuery::IsQueryEXT(const WebGLQuery* query) const
{
if (!query)
const char funcName[] = "isQueryEXT";
if (mIsLost)
return false;
if (!mContext->ValidateObjectAllowDeleted("isQueryEXT", query))
return false;
if (query->IsDeleted())
return false;
return true;
return mContext->IsQuery(query, funcName);
}
void
WebGLExtensionDisjointTimerQuery::BeginQueryEXT(GLenum target,
WebGLTimerQuery* query)
WebGLExtensionDisjointTimerQuery::BeginQueryEXT(GLenum target, WebGLQuery* query) const
{
const char funcName[] = "beginQueryEXT";
if (mIsLost)
return;
if (!mContext->ValidateObject("beginQueryEXT", query))
return;
if (query->HasEverBeenBound() && query->Target() != target) {
mContext->ErrorInvalidOperation("beginQueryEXT: Query is already bound"
" to a different target.");
return;
}
if (target != LOCAL_GL_TIME_ELAPSED_EXT) {
mContext->ErrorInvalidEnumInfo("beginQueryEXT: Can only begin on target"
" TIME_ELAPSED_EXT.", target);
return;
}
if (mActiveQuery) {
mContext->ErrorInvalidOperation("beginQueryEXT: A query is already"
" active.");
return;
}
mContext->MakeContextCurrent();
gl::GLContext* gl = mContext->GL();
gl->fBeginQuery(target, query->mGLName);
query->mTarget = LOCAL_GL_TIME_ELAPSED_EXT;
mActiveQuery = query;
mContext->BeginQuery(target, query, funcName);
}
void
WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target)
WebGLExtensionDisjointTimerQuery::EndQueryEXT(GLenum target) const
{
const char funcName[] = "endQueryEXT";
if (mIsLost)
return;
if (target != LOCAL_GL_TIME_ELAPSED_EXT) {
mContext->ErrorInvalidEnumInfo("endQueryEXT: Can only end on"
" TIME_ELAPSED_EXT.", target);
return;
}
if (!mActiveQuery) {
mContext->ErrorInvalidOperation("endQueryEXT: A query is not active.");
return;
}
mContext->MakeContextCurrent();
mContext->GL()->fEndQuery(target);
mActiveQuery->QueueAvailablity();
mActiveQuery = nullptr;
mContext->EndQuery(target, funcName);
}
void
WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLTimerQuery* query,
GLenum target)
WebGLExtensionDisjointTimerQuery::QueryCounterEXT(WebGLQuery* query, GLenum target) const
{
const char funcName[] = "queryCounterEXT";
if (mIsLost)
return;
if (!mContext->ValidateObject("queryCounterEXT", query))
if (!mContext->ValidateObject(funcName, query))
return;
if (target != LOCAL_GL_TIMESTAMP_EXT) {
mContext->ErrorInvalidEnumInfo("queryCounterEXT: requires"
" TIMESTAMP_EXT.", target);
return;
}
mContext->MakeContextCurrent();
mContext->GL()->fQueryCounter(query->mGLName, target);
query->mTarget = LOCAL_GL_TIMESTAMP_EXT;
query->QueueAvailablity();
query->QueryCounter(funcName, target);
}
void
WebGLExtensionDisjointTimerQuery::GetQueryEXT(JSContext* cx, GLenum target,
GLenum pname,
JS::MutableHandle<JS::Value> retval)
WebGLExtensionDisjointTimerQuery::GetQueryEXT(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval) const
{
const char funcName[] = "getQueryEXT";
retval.setNull();
if (mIsLost)
return;
mContext->MakeContextCurrent();
switch (pname) {
case LOCAL_GL_CURRENT_QUERY_EXT:
if (target != LOCAL_GL_TIME_ELAPSED_EXT) {
mContext->ErrorInvalidEnumInfo("getQueryEXT: Invalid query target.",
target);
return;
}
if (mActiveQuery) {
JS::Rooted<JS::Value> v(cx);
dom::GetOrCreateDOMReflector(cx, mActiveQuery.get(), &v);
retval.set(v);
} else {
retval.set(JS::NullValue());
}
break;
case LOCAL_GL_QUERY_COUNTER_BITS_EXT:
if (target != LOCAL_GL_TIME_ELAPSED_EXT &&
target != LOCAL_GL_TIMESTAMP_EXT)
{
mContext->ErrorInvalidEnumInfo("getQueryEXT: Invalid query target.",
target);
return;
}
{
GLint bits = 0;
if (mContext->HasTimestampBits()) {
mContext->GL()->fGetQueryiv(target, pname, &bits);
}
retval.set(JS::Int32Value(int32_t(bits)));
}
break;
default:
mContext->ErrorInvalidEnumInfo("getQueryEXT: Invalid query property.",
pname);
break;
}
mContext->GetQuery(cx, target, pname, retval, funcName);
}
void
WebGLExtensionDisjointTimerQuery::GetQueryObjectEXT(JSContext* cx,
WebGLTimerQuery* query,
GLenum pname,
JS::MutableHandle<JS::Value> retval)
const WebGLQuery* query, GLenum pname,
JS::MutableHandleValue retval) const
{
const char funcName[] = "getQueryObjectEXT";
retval.setNull();
if (mIsLost)
return;
if (!mContext->ValidateObject("getQueryObjectEXT", query))
return;
if (query == mActiveQuery.get()) {
mContext->ErrorInvalidOperation("getQueryObjectEXT: Query must not be"
" active.");
return;
}
mContext->MakeContextCurrent();
// XXX: Note that the query result *may change* within the same task!
// This does not follow the specification, which states that all calls
// checking query results must return the same value until the event loop
// is empty.
switch (pname) {
case LOCAL_GL_QUERY_RESULT_EXT:
{
GLuint64 result = 0;
mContext->GL()->fGetQueryObjectui64v(query->mGLName,
LOCAL_GL_QUERY_RESULT_EXT,
&result);
retval.set(JS::NumberValue(result));
}
break;
case LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT:
{
GLuint avail = 0;
mContext->GL()->fGetQueryObjectuiv(query->mGLName,
LOCAL_GL_QUERY_RESULT_AVAILABLE_EXT,
&avail);
bool canBeAvailable = query->CanBeAvailable() || gfxPrefs::WebGLImmediateQueries();
retval.set(JS::BooleanValue(bool(avail) && canBeAvailable));
}
break;
default:
mContext->ErrorInvalidEnumInfo("getQueryObjectEXT: Invalid query"
" property.", pname);
break;
}
mContext->GetQueryParameter(cx, query, pname, retval, funcName);
}
bool
@ -258,12 +124,6 @@ WebGLExtensionDisjointTimerQuery::IsSupported(const WebGLContext* webgl)
gl->IsSupported(gl::GLFeature::query_counter); // provides GL_TIMESTAMP
}
void
WebGLExtensionDisjointTimerQuery::OnMarkLost()
{
mActiveQuery = nullptr;
}
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionDisjointTimerQuery, EXT_disjoint_timer_query)
} // namespace mozilla

View File

@ -25,7 +25,6 @@ class FormatUsageAuthority;
class WebGLContext;
class WebGLShader;
class WebGLQuery;
class WebGLTimerQuery;
class WebGLVertexArray;
class WebGLExtensionBase
@ -370,29 +369,20 @@ public:
explicit WebGLExtensionDisjointTimerQuery(WebGLContext* webgl);
virtual ~WebGLExtensionDisjointTimerQuery();
already_AddRefed<WebGLTimerQuery> CreateQueryEXT();
void DeleteQueryEXT(WebGLTimerQuery* query);
bool IsQueryEXT(WebGLTimerQuery* query);
void BeginQueryEXT(GLenum target, WebGLTimerQuery* query);
void EndQueryEXT(GLenum target);
void QueryCounterEXT(WebGLTimerQuery* query, GLenum target);
void GetQueryEXT(JSContext *cx, GLenum target, GLenum pname,
JS::MutableHandle<JS::Value> retval);
void GetQueryObjectEXT(JSContext *cx, WebGLTimerQuery* query,
GLenum pname,
JS::MutableHandle<JS::Value> retval);
already_AddRefed<WebGLQuery> CreateQueryEXT() const;
void DeleteQueryEXT(WebGLQuery* query) const;
bool IsQueryEXT(const WebGLQuery* query) const;
void BeginQueryEXT(GLenum target, WebGLQuery* query) const;
void EndQueryEXT(GLenum target) const;
void QueryCounterEXT(WebGLQuery* query, GLenum target) const;
void GetQueryEXT(JSContext* cx, GLenum target, GLenum pname,
JS::MutableHandleValue retval) const;
void GetQueryObjectEXT(JSContext* cx, const WebGLQuery* query,
GLenum pname, JS::MutableHandleValue retval) const;
static bool IsSupported(const WebGLContext*);
DECL_WEBGL_EXTENSION_GOOP
private:
virtual void OnMarkLost() override;
/**
* An active TIME_ELAPSED query participating in a begin/end block.
*/
WebGLRefPtr<WebGLTimerQuery> mActiveQuery;
};
} // namespace mozilla

View File

@ -16,7 +16,7 @@ WebGLContextBoundObject::WebGLContextBoundObject(WebGLContext* webgl)
}
bool
WebGLContextBoundObject::IsCompatibleWithContext(WebGLContext* other)
WebGLContextBoundObject::IsCompatibleWithContext(const WebGLContext* other) const
{
return (mContext == other &&
mContextGeneration == other->Generation());

View File

@ -267,7 +267,7 @@ class WebGLContextBoundObject
public:
explicit WebGLContextBoundObject(WebGLContext* webgl);
bool IsCompatibleWithContext(WebGLContext* other);
bool IsCompatibleWithContext(const WebGLContext* other) const;
WebGLContext* const mContext;
protected:

View File

@ -12,22 +12,41 @@
namespace mozilla {
JSObject*
WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
class AvailableRunnable final : public Runnable
{
return dom::WebGLQueryBinding::Wrap(cx, this, givenProto);
const RefPtr<WebGLQuery> mQuery;
public:
explicit AvailableRunnable(WebGLQuery* query)
: mQuery(query)
{ }
NS_IMETHOD Run() override {
mQuery->mCanBeAvailable = true;
return NS_OK;
}
};
////
static GLuint
GenQuery(gl::GLContext* gl)
{
gl->MakeCurrent();
GLuint ret = 0;
gl->fGenQueries(1, &ret);
return ret;
}
WebGLQuery::WebGLQuery(WebGLContext* webgl)
: WebGLContextBoundObject(webgl)
, mGLName(GenQuery(mContext->gl))
, mTarget(0)
, mIsActive(false)
, mCanBeAvailable(false)
, mGLName(0)
, mType(0)
{
mContext->mQueries.insertBack(this);
mContext->MakeContextCurrent();
mContext->gl->fGenQueries(1, &mGLName);
}
void
@ -38,15 +57,212 @@ WebGLQuery::Delete()
LinkedListElement<WebGLQuery>::removeFrom(mContext->mQueries);
}
bool
WebGLQuery::IsActive() const
////
static GLenum
TargetForDriver(const gl::GLContext* gl, GLenum target)
{
if (!HasEverBeenActive())
switch (target) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
break;
default:
return target;
}
if (gl->IsSupported(gl::GLFeature::occlusion_query_boolean))
return target;
if (gl->IsSupported(gl::GLFeature::occlusion_query2))
return LOCAL_GL_ANY_SAMPLES_PASSED;
return LOCAL_GL_SAMPLES_PASSED;
}
bool
WebGLQuery::BeginQuery(GLenum target)
{
const char funcName[] = "beginQuery";
if (mTarget && target != mTarget) {
mContext->ErrorInvalidOperation("%s: Queries cannot change targets.", funcName);
return false;
}
////
mTarget = target;
mIsActive = true;
////
const auto& gl = mContext->gl;
gl->MakeCurrent();
const auto driverTarget = TargetForDriver(gl, mTarget);
gl->fBeginQuery(driverTarget, mGLName);
return true;
}
void
WebGLQuery::EndQuery()
{
mIsActive = false;
mCanBeAvailable = false;
////
const auto& gl = mContext->gl;
gl->MakeCurrent();
const auto driverTarget = TargetForDriver(gl, mTarget);
gl->fEndQuery(driverTarget);
////
NS_DispatchToCurrentThread(new AvailableRunnable(this));
}
void
WebGLQuery::GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const
{
const char funcName[] = "getQueryParameter";
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
case LOCAL_GL_QUERY_RESULT:
break;
default:
mContext->ErrorInvalidEnum("%s: Invalid pname: %s", funcName,
mContext->EnumName(pname));
return;
}
if (!mTarget) {
mContext->ErrorInvalidOperation("%s: Query has never been active.", funcName);
return;
}
if (mIsActive)
return mContext->ErrorInvalidOperation("%s: Query is still active.", funcName);
// End of validation
////
// We must usually wait for an event loop before the query can be available.
const bool canBeAvailable = (mCanBeAvailable || gfxPrefs::WebGLImmediateQueries());
if (!canBeAvailable) {
if (pname == LOCAL_GL_QUERY_RESULT_AVAILABLE) {
retval.set(JS::BooleanValue(false));
}
return;
}
const auto& gl = mContext->gl;
gl->MakeCurrent();
uint64_t val = 0;
switch (pname) {
case LOCAL_GL_QUERY_RESULT_AVAILABLE:
gl->fGetQueryObjectuiv(mGLName, pname, (GLuint*)&val);
retval.set(JS::BooleanValue(bool(val)));
return;
case LOCAL_GL_QUERY_RESULT:
switch (mTarget) {
case LOCAL_GL_TIME_ELAPSED_EXT:
case LOCAL_GL_TIMESTAMP_EXT:
if (mContext->Has64BitTimestamps()) {
gl->fGetQueryObjectui64v(mGLName, pname, &val);
break;
}
MOZ_FALLTHROUGH;
default:
gl->fGetQueryObjectuiv(mGLName, LOCAL_GL_QUERY_RESULT, (GLuint*)&val);
break;
}
switch (mTarget) {
case LOCAL_GL_ANY_SAMPLES_PASSED:
case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
retval.set(JS::BooleanValue(bool(val)));
break;
case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
case LOCAL_GL_TIME_ELAPSED_EXT:
case LOCAL_GL_TIMESTAMP_EXT:
retval.set(JS::NumberValue(val));
break;
default:
MOZ_CRASH("Bad `mTarget`.");
}
return;
default:
MOZ_CRASH("Bad `pname`.");
}
}
bool
WebGLQuery::IsQuery() const
{
if (IsDeleted())
return false;
WebGLRefPtr<WebGLQuery>& targetSlot = mContext->GetQuerySlotByTarget(mType);
if (!mTarget)
return false;
return targetSlot.get() == this;
return true;
}
void
WebGLQuery::DeleteQuery()
{
if (IsDeleted())
return;
if (mIsActive) {
EndQuery();
}
RequestDelete();
}
void
WebGLQuery::QueryCounter(const char* funcName, GLenum target)
{
if (target != LOCAL_GL_TIMESTAMP_EXT) {
mContext->ErrorInvalidEnum("%s: `target` must be TIMESTAMP_EXT.", funcName,
target);
return;
}
if (mTarget && target != mTarget) {
mContext->ErrorInvalidOperation("%s: Queries cannot change targets.", funcName);
return;
}
mTarget = target;
mCanBeAvailable = false;
const auto& gl = mContext->gl;
gl->MakeCurrent();
gl->fQueryCounter(mGLName, mTarget);
NS_DispatchToCurrentThread(new AvailableRunnable(this));
}
////
JSObject*
WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
{
return dom::WebGLQueryBinding::Wrap(cx, this, givenProto);
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQuery)

View File

@ -20,54 +20,48 @@ class WebGLQuery final
, public LinkedListElement<WebGLQuery>
, public WebGLContextBoundObject
{
friend class AvailableRunnable;
friend class WebGLRefCountedObject<WebGLQuery>;
public:
explicit WebGLQuery(WebGLContext* webgl);
const GLuint mGLName;
private:
GLenum mTarget;
bool mIsActive;
class AvailableRunnable final : public Runnable
{
public:
explicit AvailableRunnable(WebGLQuery* query) : mQuery(query) { }
bool mCanBeAvailable; // Track whether the event loop has spun
NS_IMETHOD Run() override {
mQuery->mCanBeAvailable = true;
return NS_OK;
}
private:
const RefPtr<WebGLQuery> mQuery;
};
////
public:
bool IsActive() const { return mIsActive; }
bool IsActive() const;
bool HasEverBeenActive() const {
return mType != 0;
}
// WebGLRefCountedObject
void Delete();
// nsWrapperCache
WebGLContext* GetParentObject() const {
return mContext;
}
// NS
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
////
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery)
// Track whether the event loop has spun
bool mCanBeAvailable;
explicit WebGLQuery(WebGLContext* webgl);
private:
~WebGLQuery() {
DeleteOnce();
};
GLuint mGLName;
GLenum mType;
// WebGLRefCountedObject
void Delete();
friend class WebGL2Context;
public:
WebGLContext* GetParentObject() const { return mContext; }
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
////
bool BeginQuery(GLenum target);
void DeleteQuery();
void EndQuery();
void GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const;
bool IsQuery() const;
void QueryCounter(const char* funcName, GLenum target);
};
} // namespace mozilla

View File

@ -1,75 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "WebGLTimerQuery.h"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
#include "nsContentUtils.h"
#include "WebGLContext.h"
#include "nsThreadUtils.h"
namespace mozilla {
JSObject*
WebGLTimerQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
{
return dom::WebGLTimerQueryEXTBinding::Wrap(cx, this, givenProto);
}
WebGLTimerQuery::WebGLTimerQuery(WebGLContext* webgl, GLuint name)
: WebGLContextBoundObject(webgl)
, mGLName(name)
, mTarget(LOCAL_GL_NONE)
, mCanBeAvailable(false)
{
mContext->mTimerQueries.insertBack(this);
}
WebGLTimerQuery::~WebGLTimerQuery()
{
DeleteOnce();
}
WebGLTimerQuery*
WebGLTimerQuery::Create(WebGLContext* webgl)
{
GLuint name = 0;
webgl->MakeContextCurrent();
webgl->gl->fGenQueries(1, &name);
return new WebGLTimerQuery(webgl, name);
}
void
WebGLTimerQuery::Delete()
{
gl::GLContext* gl = mContext->GL();
gl->MakeCurrent();
gl->fDeleteQueries(1, &mGLName);
LinkedListElement<WebGLTimerQuery>::removeFrom(mContext->mTimerQueries);
}
WebGLContext*
WebGLTimerQuery::GetParentObject() const
{
return mContext;
}
void
WebGLTimerQuery::QueueAvailablity()
{
RefPtr<WebGLTimerQuery> self = this;
NS_DispatchToCurrentThread(NS_NewRunnableFunction([self] { self->mCanBeAvailable = true; }));
}
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLTimerQuery)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLTimerQuery, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLTimerQuery, Release)
} // namespace mozilla

View File

@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef WEBGL_TIMER_QUERY_H_
#define WEBGL_TIMER_QUERY_H_
#include "GLConsts.h"
#include "nsWrapperCache.h"
#include "WebGLObjectModel.h"
namespace mozilla {
class WebGLTimerQuery final
: public nsWrapperCache
, public WebGLRefCountedObject<WebGLTimerQuery>
, public LinkedListElement<WebGLTimerQuery>
, public WebGLContextBoundObject
{
public:
static WebGLTimerQuery* Create(WebGLContext* webgl);
void Delete();
bool HasEverBeenBound() const { return mTarget != LOCAL_GL_NONE; }
bool CanBeAvailable() const { return mCanBeAvailable; }
void QueueAvailablity();
GLenum Target() const { return mTarget; }
WebGLContext* GetParentObject() const;
// NS
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
const GLenum mGLName;
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLTimerQuery)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLTimerQuery)
private:
WebGLTimerQuery(WebGLContext* webgl, GLuint name);
~WebGLTimerQuery();
GLenum mTarget;
bool mCanBeAvailable;
friend class WebGLExtensionDisjointTimerQuery;
};
} // namespace mozilla
#endif // WEBGL_TIMER_QUERY_H_

View File

@ -148,7 +148,6 @@ UNIFIED_SOURCES += [
'WebGLTexelConversions.cpp',
'WebGLTexture.cpp',
'WebGLTextureUpload.cpp',
'WebGLTimerQuery.cpp',
'WebGLTransformFeedback.cpp',
'WebGLUniformLocation.cpp',
'WebGLValidateStrings.cpp',