LCOV - code coverage report
Current view: top level - dom/canvas - WebGLQuery.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 120 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 20 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       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/. */
       5             : 
       6             : #include "WebGLQuery.h"
       7             : 
       8             : #include "gfxPrefs.h"
       9             : #include "GLContext.h"
      10             : #include "mozilla/dom/WebGL2RenderingContextBinding.h"
      11             : #include "nsContentUtils.h"
      12             : #include "WebGLContext.h"
      13             : 
      14             : namespace mozilla {
      15             : 
      16           0 : class AvailableRunnable final : public Runnable
      17             : {
      18             :     const RefPtr<WebGLQuery> mQuery;
      19             : 
      20             : public:
      21           0 :   explicit AvailableRunnable(WebGLQuery* query)
      22           0 :     : Runnable("AvailableRunnable")
      23           0 :     , mQuery(query)
      24             :   {
      25           0 :   }
      26             : 
      27           0 :   NS_IMETHOD Run() override
      28             :   {
      29           0 :     mQuery->mCanBeAvailable = true;
      30           0 :     return NS_OK;
      31             :     }
      32             : };
      33             : 
      34             : ////
      35             : 
      36             : static GLuint
      37           0 : GenQuery(gl::GLContext* gl)
      38             : {
      39           0 :     gl->MakeCurrent();
      40             : 
      41           0 :     GLuint ret = 0;
      42           0 :     gl->fGenQueries(1, &ret);
      43           0 :     return ret;
      44             : }
      45             : 
      46           0 : WebGLQuery::WebGLQuery(WebGLContext* webgl)
      47             :     : WebGLRefCountedObject(webgl)
      48           0 :     , mGLName(GenQuery(mContext->gl))
      49             :     , mTarget(0)
      50             :     , mActiveSlot(nullptr)
      51           0 :     , mCanBeAvailable(false)
      52             : {
      53           0 :     mContext->mQueries.insertBack(this);
      54           0 : }
      55             : 
      56             : void
      57           0 : WebGLQuery::Delete()
      58             : {
      59           0 :     mContext->MakeContextCurrent();
      60           0 :     mContext->gl->fDeleteQueries(1, &mGLName);
      61           0 :     LinkedListElement<WebGLQuery>::removeFrom(mContext->mQueries);
      62           0 : }
      63             : 
      64             : ////
      65             : 
      66             : static GLenum
      67           0 : TargetForDriver(const gl::GLContext* gl, GLenum target)
      68             : {
      69           0 :     switch (target) {
      70             :     case LOCAL_GL_ANY_SAMPLES_PASSED:
      71             :     case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
      72           0 :         break;
      73             : 
      74             :     default:
      75           0 :         return target;
      76             :     }
      77             : 
      78           0 :     if (gl->IsSupported(gl::GLFeature::occlusion_query_boolean))
      79           0 :         return target;
      80             : 
      81           0 :     if (gl->IsSupported(gl::GLFeature::occlusion_query2))
      82           0 :         return LOCAL_GL_ANY_SAMPLES_PASSED;
      83             : 
      84           0 :     return LOCAL_GL_SAMPLES_PASSED;
      85             : }
      86             : 
      87             : void
      88           0 : WebGLQuery::BeginQuery(GLenum target, WebGLRefPtr<WebGLQuery>& slot)
      89             : {
      90           0 :     const char funcName[] = "beginQuery";
      91             : 
      92           0 :     if (mTarget && target != mTarget) {
      93           0 :         mContext->ErrorInvalidOperation("%s: Queries cannot change targets.", funcName);
      94           0 :         return;
      95             :     }
      96             : 
      97             :     ////
      98             : 
      99           0 :     mTarget = target;
     100           0 :     mActiveSlot = &slot;
     101           0 :     *mActiveSlot = this;
     102             : 
     103             :     ////
     104             : 
     105           0 :     const auto& gl = mContext->gl;
     106           0 :     gl->MakeCurrent();
     107             : 
     108           0 :     const auto driverTarget = TargetForDriver(gl, mTarget);
     109           0 :     gl->fBeginQuery(driverTarget, mGLName);
     110             : }
     111             : 
     112             : void
     113           0 : WebGLQuery::EndQuery()
     114             : {
     115           0 :     *mActiveSlot = nullptr;
     116           0 :     mActiveSlot = nullptr;
     117           0 :     mCanBeAvailable = false;
     118             : 
     119             :     ////
     120             : 
     121           0 :     const auto& gl = mContext->gl;
     122           0 :     gl->MakeCurrent();
     123             : 
     124           0 :     const auto driverTarget = TargetForDriver(gl, mTarget);
     125           0 :     gl->fEndQuery(driverTarget);
     126             : 
     127             :     ////
     128             : 
     129           0 :     NS_DispatchToCurrentThread(new AvailableRunnable(this));
     130           0 : }
     131             : 
     132             : void
     133           0 : WebGLQuery::GetQueryParameter(GLenum pname, JS::MutableHandleValue retval) const
     134             : {
     135           0 :     const char funcName[] = "getQueryParameter";
     136             : 
     137           0 :     switch (pname) {
     138             :     case LOCAL_GL_QUERY_RESULT_AVAILABLE:
     139             :     case LOCAL_GL_QUERY_RESULT:
     140           0 :         break;
     141             : 
     142             :     default:
     143           0 :         mContext->ErrorInvalidEnumArg(funcName, "pname", pname);
     144           0 :         return;
     145             :     }
     146             : 
     147           0 :     if (!mTarget) {
     148           0 :         mContext->ErrorInvalidOperation("%s: Query has never been active.", funcName);
     149           0 :         return;
     150             :     }
     151             : 
     152           0 :     if (mActiveSlot)
     153           0 :         return mContext->ErrorInvalidOperation("%s: Query is still active.", funcName);
     154             : 
     155             :     // End of validation
     156             :     ////
     157             : 
     158             :     // We must usually wait for an event loop before the query can be available.
     159           0 :     const bool canBeAvailable = (mCanBeAvailable || gfxPrefs::WebGLImmediateQueries());
     160           0 :     if (!canBeAvailable) {
     161           0 :         if (pname == LOCAL_GL_QUERY_RESULT_AVAILABLE) {
     162           0 :             retval.set(JS::BooleanValue(false));
     163             :         }
     164           0 :         return;
     165             :     }
     166             : 
     167           0 :     const auto& gl = mContext->gl;
     168           0 :     gl->MakeCurrent();
     169             : 
     170           0 :     uint64_t val = 0;
     171           0 :     switch (pname) {
     172             :     case LOCAL_GL_QUERY_RESULT_AVAILABLE:
     173           0 :         gl->fGetQueryObjectuiv(mGLName, pname, (GLuint*)&val);
     174           0 :         retval.set(JS::BooleanValue(bool(val)));
     175           0 :         return;
     176             : 
     177             :     case LOCAL_GL_QUERY_RESULT:
     178           0 :         switch (mTarget) {
     179             :         case LOCAL_GL_TIME_ELAPSED_EXT:
     180             :         case LOCAL_GL_TIMESTAMP_EXT:
     181           0 :             if (mContext->Has64BitTimestamps()) {
     182           0 :                 gl->fGetQueryObjectui64v(mGLName, pname, &val);
     183           0 :                 break;
     184             :             }
     185             :             MOZ_FALLTHROUGH;
     186             : 
     187             :         default:
     188           0 :             gl->fGetQueryObjectuiv(mGLName, LOCAL_GL_QUERY_RESULT, (GLuint*)&val);
     189           0 :             break;
     190             :         }
     191             : 
     192           0 :         switch (mTarget) {
     193             :         case LOCAL_GL_ANY_SAMPLES_PASSED:
     194             :         case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
     195           0 :             retval.set(JS::BooleanValue(bool(val)));
     196           0 :             break;
     197             : 
     198             :         case LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
     199             :         case LOCAL_GL_TIME_ELAPSED_EXT:
     200             :         case LOCAL_GL_TIMESTAMP_EXT:
     201           0 :             retval.set(JS::NumberValue(val));
     202           0 :             break;
     203             : 
     204             :         default:
     205           0 :             MOZ_CRASH("Bad `mTarget`.");
     206             :         }
     207           0 :         return;
     208             : 
     209             :     default:
     210           0 :         MOZ_CRASH("Bad `pname`.");
     211             :     }
     212             : }
     213             : 
     214             : bool
     215           0 : WebGLQuery::IsQuery() const
     216             : {
     217           0 :     MOZ_ASSERT(!IsDeleted());
     218             : 
     219           0 :     if (!mTarget)
     220           0 :         return false;
     221             : 
     222           0 :     return true;
     223             : }
     224             : 
     225             : void
     226           0 : WebGLQuery::DeleteQuery()
     227             : {
     228           0 :     MOZ_ASSERT(!IsDeleteRequested());
     229             : 
     230           0 :     if (mActiveSlot) {
     231           0 :         EndQuery();
     232             :     }
     233             : 
     234           0 :     RequestDelete();
     235           0 : }
     236             : 
     237             : void
     238           0 : WebGLQuery::QueryCounter(const char* funcName, GLenum target)
     239             : {
     240           0 :     if (target != LOCAL_GL_TIMESTAMP_EXT) {
     241           0 :         mContext->ErrorInvalidEnum("%s: `target` must be TIMESTAMP_EXT.", funcName);
     242           0 :         return;
     243             :     }
     244             : 
     245           0 :     if (mTarget && target != mTarget) {
     246           0 :         mContext->ErrorInvalidOperation("%s: Queries cannot change targets.", funcName);
     247           0 :         return;
     248             :     }
     249             : 
     250           0 :     mTarget = target;
     251           0 :     mCanBeAvailable = false;
     252             : 
     253           0 :     const auto& gl = mContext->gl;
     254           0 :     gl->MakeCurrent();
     255           0 :     gl->fQueryCounter(mGLName, mTarget);
     256             : 
     257           0 :     NS_DispatchToCurrentThread(new AvailableRunnable(this));
     258             : }
     259             : 
     260             : ////
     261             : 
     262             : JSObject*
     263           0 : WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
     264             : {
     265           0 :     return dom::WebGLQueryBinding::Wrap(cx, this, givenProto);
     266             : }
     267             : 
     268           0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLQuery)
     269             : 
     270           0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLQuery, AddRef)
     271           0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLQuery, Release)
     272             : 
     273             : } // namespace mozilla

Generated by: LCOV version 1.13