summaryrefslogtreecommitdiffstats
path: root/dom/canvas/WebGL2ContextSync.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/WebGL2ContextSync.cpp')
-rw-r--r--dom/canvas/WebGL2ContextSync.cpp57
1 files changed, 46 insertions, 11 deletions
diff --git a/dom/canvas/WebGL2ContextSync.cpp b/dom/canvas/WebGL2ContextSync.cpp
index b0092ca682..e5a1b1bc7b 100644
--- a/dom/canvas/WebGL2ContextSync.cpp
+++ b/dom/canvas/WebGL2ContextSync.cpp
@@ -29,10 +29,12 @@ RefPtr<WebGLSync> WebGL2Context::FenceSync(GLenum condition, GLbitfield flags) {
}
RefPtr<WebGLSync> globj = new WebGLSync(this, condition, flags);
+ mPendingSyncs.emplace_back(globj);
+ EnsurePollPendingSyncs_Pending();
return globj;
}
-GLenum WebGL2Context::ClientWaitSync(const WebGLSync& sync, GLbitfield flags,
+GLenum WebGL2Context::ClientWaitSync(WebGLSync& sync, GLbitfield flags,
GLuint64 timeout) {
const FuncScope funcScope(*this, "clientWaitSync");
if (IsContextLost()) return LOCAL_GL_WAIT_FAILED;
@@ -44,19 +46,52 @@ GLenum WebGL2Context::ClientWaitSync(const WebGLSync& sync, GLbitfield flags,
return LOCAL_GL_WAIT_FAILED;
}
- if (timeout > kMaxClientWaitSyncTimeoutNS) {
- ErrorInvalidOperation("`timeout` must not exceed %s nanoseconds.",
- "MAX_CLIENT_WAIT_TIMEOUT_WEBGL");
- return LOCAL_GL_WAIT_FAILED;
- }
-
- const auto ret = gl->fClientWaitSync(sync.mGLName, flags, timeout);
+ const auto ret = sync.ClientWaitSync(flags, timeout);
+ return UnderlyingValue(ret);
+}
- if (ret == LOCAL_GL_CONDITION_SATISFIED || ret == LOCAL_GL_ALREADY_SIGNALED) {
- sync.MarkSignaled();
+void WebGLContext::EnsurePollPendingSyncs_Pending() const {
+ if (mPollPendingSyncs_Pending) return;
+ mPollPendingSyncs_Pending = NS_NewRunnableFunction(
+ "WebGLContext::PollPendingSyncs", [weak = WeakPtr{this}]() {
+ if (const auto strong = RefPtr{weak.get()}) {
+ strong->mPollPendingSyncs_Pending = nullptr;
+ strong->PollPendingSyncs();
+ if (strong->mPendingSyncs.size()) {
+ // Not done yet...
+ strong->EnsurePollPendingSyncs_Pending();
+ }
+ }
+ });
+ if (const auto eventTarget = GetCurrentSerialEventTarget()) {
+ eventTarget->DelayedDispatch(do_AddRef(mPollPendingSyncs_Pending),
+ kPollPendingSyncs_DelayMs);
+ } else {
+ NS_WARNING(
+ "[EnsurePollPendingSyncs_Pending] GetCurrentSerialEventTarget() -> "
+ "nullptr");
}
+}
- return ret;
+void WebGLContext::PollPendingSyncs() const {
+ const FuncScope funcScope(*this, "<pollPendingSyncs>");
+ if (IsContextLost()) return;
+
+ while (mPendingSyncs.size()) {
+ if (const auto sync = RefPtr{mPendingSyncs.front().get()}) {
+ const auto res = sync->ClientWaitSync(0, 0);
+ switch (res) {
+ case ClientWaitSyncResult::WAIT_FAILED:
+ case ClientWaitSyncResult::TIMEOUT_EXPIRED:
+ return;
+ case ClientWaitSyncResult::CONDITION_SATISFIED:
+ case ClientWaitSyncResult::ALREADY_SIGNALED:
+ // Communication back to child happens in sync->lientWaitSync.
+ break;
+ }
+ }
+ mPendingSyncs.pop_front();
+ }
}
} // namespace mozilla