tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WebGLQuery.cpp (3778B)


      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/. */
      5 
      6 #include "WebGLQuery.h"
      7 
      8 #include "GLContext.h"
      9 #include "WebGLContext.h"
     10 #include "mozilla/StaticPrefs_webgl.h"
     11 #include "mozilla/dom/WebGL2RenderingContextBinding.h"
     12 #include "nsContentUtils.h"
     13 
     14 namespace mozilla {
     15 
     16 ////
     17 
     18 static GLuint GenQuery(gl::GLContext* gl) {
     19  GLuint ret = 0;
     20  gl->fGenQueries(1, &ret);
     21  return ret;
     22 }
     23 
     24 WebGLQuery::WebGLQuery(WebGLContext* webgl)
     25    : WebGLContextBoundObject(webgl),
     26      mGLName(GenQuery(mContext->gl)),
     27      mTarget(0),
     28      mActiveSlot(nullptr) {}
     29 
     30 WebGLQuery::~WebGLQuery() {
     31  if (!mContext) return;
     32  mContext->gl->fDeleteQueries(1, &mGLName);
     33 }
     34 
     35 ////
     36 
     37 static GLenum TargetForDriver(const gl::GLContext* gl, GLenum target) {
     38  switch (target) {
     39    case LOCAL_GL_ANY_SAMPLES_PASSED:
     40    case LOCAL_GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
     41      break;
     42 
     43    default:
     44      return target;
     45  }
     46 
     47  if (gl->IsSupported(gl::GLFeature::occlusion_query_boolean)) return target;
     48 
     49  if (gl->IsSupported(gl::GLFeature::occlusion_query2))
     50    return LOCAL_GL_ANY_SAMPLES_PASSED;
     51 
     52  return LOCAL_GL_SAMPLES_PASSED;
     53 }
     54 
     55 void WebGLQuery::BeginQuery(GLenum target, RefPtr<WebGLQuery>& slot) {
     56  mTarget = target;
     57  mActiveSlot = &slot;
     58  *mActiveSlot = this;
     59 
     60  ////
     61 
     62  const auto& gl = mContext->gl;
     63 
     64  const auto driverTarget = TargetForDriver(gl, mTarget);
     65  gl->fBeginQuery(driverTarget, mGLName);
     66 }
     67 
     68 void WebGLQuery::EndQuery() {
     69  *mActiveSlot = nullptr;
     70  mActiveSlot = nullptr;
     71  mCanBeAvailable = false;
     72 
     73  ////
     74 
     75  const auto& gl = mContext->gl;
     76 
     77  const auto driverTarget = TargetForDriver(gl, mTarget);
     78  gl->fEndQuery(driverTarget);
     79 }
     80 
     81 Maybe<double> WebGLQuery::GetQueryParameter(GLenum pname) const {
     82  switch (pname) {
     83    case LOCAL_GL_QUERY_RESULT_AVAILABLE:
     84    case LOCAL_GL_QUERY_RESULT:
     85      break;
     86 
     87    default:
     88      mContext->ErrorInvalidEnumInfo("pname", pname);
     89      return Nothing();
     90  }
     91 
     92  if (!mTarget) {
     93    mContext->ErrorInvalidOperation("Query has never been active.");
     94    return Nothing();
     95  }
     96 
     97  if (mActiveSlot) {
     98    mContext->ErrorInvalidOperation("Query is still active.");
     99    return Nothing();
    100  }
    101 
    102  // End of validation
    103  ////
    104 
    105  const auto& gl = mContext->gl;
    106 
    107  uint64_t val = 0;
    108  switch (pname) {
    109    case LOCAL_GL_QUERY_RESULT_AVAILABLE:
    110      gl->fGetQueryObjectuiv(mGLName, pname, (GLuint*)&val);
    111      return Some(static_cast<bool>(val));
    112 
    113    case LOCAL_GL_QUERY_RESULT:
    114      switch (mTarget) {
    115        case LOCAL_GL_TIME_ELAPSED_EXT:
    116        case LOCAL_GL_TIMESTAMP_EXT:
    117          if (mContext->Has64BitTimestamps()) {
    118            gl->fGetQueryObjectui64v(mGLName, pname, &val);
    119            break;
    120          }
    121          [[fallthrough]];
    122 
    123        default:
    124          gl->fGetQueryObjectuiv(mGLName, LOCAL_GL_QUERY_RESULT, (GLuint*)&val);
    125          break;
    126      }
    127 
    128      switch (mTarget) {
    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:
    134          return Some(val);
    135      }
    136      MOZ_CRASH("Bad `mTarget`.");
    137 
    138    default:
    139      MOZ_CRASH("Bad `pname`.");
    140  }
    141 }
    142 
    143 void WebGLQuery::QueryCounter() {
    144  const GLenum target = LOCAL_GL_TIMESTAMP_EXT;
    145  if (mTarget && target != mTarget) {
    146    mContext->ErrorInvalidOperation("Queries cannot change targets.");
    147    return;
    148  }
    149 
    150  mTarget = target;
    151  mCanBeAvailable = false;
    152 
    153  const auto& gl = mContext->gl;
    154  gl->fQueryCounter(mGLName, mTarget);
    155 }
    156 
    157 }  // namespace mozilla