From 603c0dca5a241f03d742e7ba7d16ceff168a3a7e Mon Sep 17 00:00:00 2001 From: Dan Glastonbury Date: Fri, 17 Apr 2015 11:17:07 +1000 Subject: [PATCH] Bug 1155470 - Fix queries. r=jgilbert es3fTransformFeedbackTests exposed problems with queries. Queries are needed to get the number of transformed primitives. --- dom/canvas/WebGL1Context.cpp | 7 ++ dom/canvas/WebGL1Context.h | 2 +- dom/canvas/WebGL2Context.h | 4 +- dom/canvas/WebGL2ContextQueries.cpp | 102 +++++++++++++++++----------- dom/canvas/WebGLContext.h | 3 +- dom/canvas/WebGLQuery.cpp | 5 +- 6 files changed, 77 insertions(+), 46 deletions(-) diff --git a/dom/canvas/WebGL1Context.cpp b/dom/canvas/WebGL1Context.cpp index 5dec3638e44d..2e65e8729d8f 100644 --- a/dom/canvas/WebGL1Context.cpp +++ b/dom/canvas/WebGL1Context.cpp @@ -31,6 +31,13 @@ WebGL1Context::WrapObject(JSContext* cx, JS::Handle aGivenProto) return dom::WebGLRenderingContextBinding::Wrap(cx, this, aGivenProto); } +bool +WebGL1Context::ValidateQueryTarget(GLenum target, const char* info) +{ + // TODO: Implement this for EXT_disjoint_timer + return false; +} + } // namespace mozilla nsresult diff --git a/dom/canvas/WebGL1Context.h b/dom/canvas/WebGL1Context.h index 084e086d4d29..a20845a6b627 100644 --- a/dom/canvas/WebGL1Context.h +++ b/dom/canvas/WebGL1Context.h @@ -35,7 +35,7 @@ private: virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override; virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) override; virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) override; - + virtual bool ValidateQueryTarget(GLenum target, const char* info) override; virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override; }; diff --git a/dom/canvas/WebGL2Context.h b/dom/canvas/WebGL2Context.h index 22936bd7ffd2..fed64e4c6180 100644 --- a/dom/canvas/WebGL2Context.h +++ b/dom/canvas/WebGL2Context.h @@ -355,6 +355,8 @@ private: JS::Value GetTexParameterInternal(const TexTarget& target, GLenum pname) override; + void UpdateBoundQuery(GLenum target, WebGLQuery* query); + bool ValidateSizedInternalFormat(GLenum internalFormat, const char* info); bool ValidateTexStorage(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, @@ -365,7 +367,7 @@ private: virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) override; virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) override; virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) override; - + virtual bool ValidateQueryTarget(GLenum target, const char* info) override; virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) override; }; diff --git a/dom/canvas/WebGL2ContextQueries.cpp b/dom/canvas/WebGL2ContextQueries.cpp index 8a5660e3cdd2..91d83bfa8fb4 100644 --- a/dom/canvas/WebGL2ContextQueries.cpp +++ b/dom/canvas/WebGL2ContextQueries.cpp @@ -7,8 +7,7 @@ #include "GLContext.h" #include "WebGLQuery.h" -using namespace mozilla; -using namespace mozilla::dom; +namespace mozilla { /* * We fake ANY_SAMPLES_PASSED and ANY_SAMPLES_PASSED_CONSERVATIVE with @@ -26,14 +25,14 @@ GetQueryTargetEnumString(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; + 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; } MOZ_ASSERT(false, "Unknown query `target`."); @@ -56,19 +55,23 @@ SimulateOcclusionQueryTarget(const gl::GLContext* gl, GLenum target) return LOCAL_GL_SAMPLES_PASSED; } -WebGLRefPtr* -WebGLContext::GetQueryTargetSlot(GLenum target) +WebGLRefPtr& +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_ANY_SAMPLES_PASSED: + case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + return mActiveOcclusionQuery; - case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: - return &mActiveTransformFeedbackQuery; + case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + return mActiveTransformFeedbackQuery; + + default: + MOZ_CRASH("Should not get here."); } - - return nullptr; } @@ -152,11 +155,8 @@ WebGL2Context::BeginQuery(GLenum target, WebGLQuery* query) if (IsContextLost()) return; - WebGLRefPtr* targetSlot = GetQueryTargetSlot(target); - if (!targetSlot) { - ErrorInvalidEnum("beginQuery: unknown query target"); + if (!ValidateQueryTarget(target, "beginQuery")) return; - } if (!query) { /* From GLES's EXT_occlusion_query_boolean: @@ -193,10 +193,10 @@ WebGL2Context::BeginQuery(GLenum target, WebGLQuery* query) return; } - if (*targetSlot) { - ErrorInvalidOperation("beginQuery: An other query already active."); - return; - } + WebGLRefPtr& querySlot = GetQuerySlotByTarget(target); + WebGLQuery* activeQuery = querySlot.get(); + if (activeQuery) + return ErrorInvalidOperation("beginQuery: An other query already active."); if (!query->HasEverBeenActive()) query->mType = target; @@ -211,7 +211,7 @@ WebGL2Context::BeginQuery(GLenum target, WebGLQuery* query) query->mGLName); } - *targetSlot = query; + UpdateBoundQuery(target, query); } void @@ -220,14 +220,13 @@ WebGL2Context::EndQuery(GLenum target) if (IsContextLost()) return; - WebGLRefPtr* targetSlot = GetQueryTargetSlot(target); - if (!targetSlot) { - ErrorInvalidEnum("endQuery: unknown query target"); + if (!ValidateQueryTarget(target, "endQuery")) return; - } - if (!*targetSlot || - target != (*targetSlot)->mType) + WebGLRefPtr& 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 @@ -255,7 +254,7 @@ WebGL2Context::EndQuery(GLenum target) gl->fEndQuery(SimulateOcclusionQueryTarget(gl, target)); } - *targetSlot = nullptr; + UpdateBoundQuery(target, nullptr); } already_AddRefed @@ -264,11 +263,8 @@ WebGL2Context::GetQuery(GLenum target, GLenum pname) if (IsContextLost()) return nullptr; - WebGLRefPtr* targetSlot = GetQueryTargetSlot(target); - if (!targetSlot) { - ErrorInvalidEnum("getQuery: unknown query target"); + if (!ValidateQueryTarget(target, "getQuery")) return nullptr; - } if (pname != LOCAL_GL_CURRENT_QUERY) { /* OpenGL ES 3.0 spec 6.1.7: @@ -278,7 +274,9 @@ WebGL2Context::GetQuery(GLenum target, GLenum pname) return nullptr; } - nsRefPtr tmp = targetSlot->get(); + WebGLRefPtr& targetSlot = GetQuerySlotByTarget(target); + + nsRefPtr tmp = targetSlot.get(); return tmp.forget(); } @@ -353,3 +351,27 @@ WebGL2Context::GetQueryParameter(JSContext*, WebGLQuery* query, GLenum pname, ErrorInvalidEnum("getQueryObject: `pname` must be QUERY_RESULT{_AVAILABLE}."); } + +void +WebGL2Context::UpdateBoundQuery(GLenum target, WebGLQuery* query) +{ + WebGLRefPtr& 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; + } +} + +} // namespace mozilla diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index 8338563dfda6..b6ada05d4261 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -936,7 +936,7 @@ protected: // ----------------------------------------------------------------------------- // Queries (WebGL2ContextQueries.cpp) protected: - WebGLRefPtr* GetQueryTargetSlot(GLenum target); + WebGLRefPtr& GetQuerySlotByTarget(GLenum target); WebGLRefPtr mActiveOcclusionQuery; WebGLRefPtr mActiveTransformFeedbackQuery; @@ -1389,6 +1389,7 @@ private: virtual bool ValidateBufferIndexedTarget(GLenum target, const char* info) = 0; virtual bool ValidateBufferForTarget(GLenum target, WebGLBuffer* buffer, const char* info) = 0; virtual bool ValidateBufferUsageEnum(GLenum usage, const char* info) = 0; + virtual bool ValidateQueryTarget(GLenum usage, const char* info) = 0; virtual bool ValidateUniformMatrixTranspose(bool transpose, const char* info) = 0; protected: diff --git a/dom/canvas/WebGLQuery.cpp b/dom/canvas/WebGLQuery.cpp index afa2940d10f8..a17bd041630d 100644 --- a/dom/canvas/WebGLQuery.cpp +++ b/dom/canvas/WebGLQuery.cpp @@ -40,10 +40,9 @@ WebGLQuery::Delete() bool WebGLQuery::IsActive() const { - WebGLRefPtr* targetSlot = mContext->GetQueryTargetSlot(mType); + WebGLRefPtr& targetSlot = mContext->GetQuerySlotByTarget(mType); - MOZ_ASSERT(targetSlot, "unknown query object's type"); - return targetSlot && *targetSlot == this; + return targetSlot.get() == this; } NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQuery)