tor-browser

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

WebGL2ContextSync.cpp (3209B)


      1 /* -*- Mode: C++; tab-width: 4; 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 "GLContext.h"
      7 #include "WebGL2Context.h"
      8 #include "WebGLSync.h"
      9 #include "mozilla/StaticPrefs_webgl.h"
     10 
     11 namespace mozilla {
     12 
     13 // -------------------------------------------------------------------------
     14 // Sync objects
     15 
     16 RefPtr<WebGLSync> WebGL2Context::FenceSync(GLenum condition, GLbitfield flags) {
     17  const FuncScope funcScope(*this, "fenceSync");
     18  if (IsContextLost()) return nullptr;
     19 
     20  if (condition != LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE) {
     21    ErrorInvalidEnum("condition must be SYNC_GPU_COMMANDS_COMPLETE");
     22    return nullptr;
     23  }
     24 
     25  if (flags != 0) {
     26    ErrorInvalidValue("flags must be 0");
     27    return nullptr;
     28  }
     29 
     30  RefPtr<WebGLSync> globj = new WebGLSync(this, condition, flags);
     31  mPendingSyncs.emplace_back(globj);
     32  EnsurePollPendingSyncs_Pending();
     33  return globj;
     34 }
     35 
     36 GLenum WebGL2Context::ClientWaitSync(WebGLSync& sync, GLbitfield flags,
     37                                     GLuint64 timeout) {
     38  const FuncScope funcScope(*this, "clientWaitSync");
     39  if (IsContextLost()) return LOCAL_GL_WAIT_FAILED;
     40 
     41  if (!ValidateObject("sync", sync)) return LOCAL_GL_WAIT_FAILED;
     42 
     43  if (flags != 0 && flags != LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT) {
     44    ErrorInvalidValue("`flags` must be SYNC_FLUSH_COMMANDS_BIT or 0.");
     45    return LOCAL_GL_WAIT_FAILED;
     46  }
     47 
     48  const auto ret = sync.ClientWaitSync(flags, timeout);
     49  return UnderlyingValue(ret);
     50 }
     51 
     52 void WebGLContext::EnsurePollPendingSyncs_Pending() const {
     53  if (mPollPendingSyncs_Pending) return;
     54  mPollPendingSyncs_Pending = NS_NewRunnableFunction(
     55      "WebGLContext::PollPendingSyncs", [weak = WeakPtr{this}]() {
     56        if (const auto strong = RefPtr{weak.get()}) {
     57          strong->mPollPendingSyncs_Pending = nullptr;
     58          strong->PollPendingSyncs();
     59          if (strong->mPendingSyncs.size()) {
     60            // Not done yet...
     61            strong->EnsurePollPendingSyncs_Pending();
     62          }
     63        }
     64      });
     65  if (const auto eventTarget = GetCurrentSerialEventTarget()) {
     66    eventTarget->DelayedDispatch(do_AddRef(mPollPendingSyncs_Pending),
     67                                 kPollPendingSyncs_DelayMs);
     68  } else {
     69    NS_WARNING(
     70        "[EnsurePollPendingSyncs_Pending] GetCurrentSerialEventTarget() -> "
     71        "nullptr");
     72  }
     73 }
     74 
     75 void WebGLContext::PollPendingSyncs() const {
     76  const FuncScope funcScope(*this, "<pollPendingSyncs>");
     77  if (IsContextLost()) return;
     78 
     79  while (mPendingSyncs.size()) {
     80    if (const auto sync = RefPtr{mPendingSyncs.front().get()}) {
     81      const auto res = sync->ClientWaitSync(0, 0);
     82      switch (res) {
     83        case ClientWaitSyncResult::WAIT_FAILED:
     84        case ClientWaitSyncResult::TIMEOUT_EXPIRED:
     85          return;
     86        case ClientWaitSyncResult::CONDITION_SATISFIED:
     87        case ClientWaitSyncResult::ALREADY_SIGNALED:
     88          // Communication back to child happens in sync->lientWaitSync.
     89          break;
     90      }
     91    }
     92    mPendingSyncs.pop_front();
     93  }
     94 }
     95 
     96 }  // namespace mozilla