Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / canvas / WebGL2ContextSync.cpp
blobe5a1b1bc7b66b5f028ca58f45086a5110e95f705
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/. */
6 #include "WebGL2Context.h"
8 #include "GLContext.h"
9 #include "WebGLSync.h"
10 #include "mozilla/StaticPrefs_webgl.h"
12 namespace mozilla {
14 // -------------------------------------------------------------------------
15 // Sync objects
17 RefPtr<WebGLSync> WebGL2Context::FenceSync(GLenum condition, GLbitfield flags) {
18 const FuncScope funcScope(*this, "fenceSync");
19 if (IsContextLost()) return nullptr;
21 if (condition != LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE) {
22 ErrorInvalidEnum("condition must be SYNC_GPU_COMMANDS_COMPLETE");
23 return nullptr;
26 if (flags != 0) {
27 ErrorInvalidValue("flags must be 0");
28 return nullptr;
31 RefPtr<WebGLSync> globj = new WebGLSync(this, condition, flags);
32 mPendingSyncs.emplace_back(globj);
33 EnsurePollPendingSyncs_Pending();
34 return globj;
37 GLenum WebGL2Context::ClientWaitSync(WebGLSync& sync, GLbitfield flags,
38 GLuint64 timeout) {
39 const FuncScope funcScope(*this, "clientWaitSync");
40 if (IsContextLost()) return LOCAL_GL_WAIT_FAILED;
42 if (!ValidateObject("sync", sync)) return LOCAL_GL_WAIT_FAILED;
44 if (flags != 0 && flags != LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT) {
45 ErrorInvalidValue("`flags` must be SYNC_FLUSH_COMMANDS_BIT or 0.");
46 return LOCAL_GL_WAIT_FAILED;
49 const auto ret = sync.ClientWaitSync(flags, timeout);
50 return UnderlyingValue(ret);
53 void WebGLContext::EnsurePollPendingSyncs_Pending() const {
54 if (mPollPendingSyncs_Pending) return;
55 mPollPendingSyncs_Pending = NS_NewRunnableFunction(
56 "WebGLContext::PollPendingSyncs", [weak = WeakPtr{this}]() {
57 if (const auto strong = RefPtr{weak.get()}) {
58 strong->mPollPendingSyncs_Pending = nullptr;
59 strong->PollPendingSyncs();
60 if (strong->mPendingSyncs.size()) {
61 // Not done yet...
62 strong->EnsurePollPendingSyncs_Pending();
65 });
66 if (const auto eventTarget = GetCurrentSerialEventTarget()) {
67 eventTarget->DelayedDispatch(do_AddRef(mPollPendingSyncs_Pending),
68 kPollPendingSyncs_DelayMs);
69 } else {
70 NS_WARNING(
71 "[EnsurePollPendingSyncs_Pending] GetCurrentSerialEventTarget() -> "
72 "nullptr");
76 void WebGLContext::PollPendingSyncs() const {
77 const FuncScope funcScope(*this, "<pollPendingSyncs>");
78 if (IsContextLost()) return;
80 while (mPendingSyncs.size()) {
81 if (const auto sync = RefPtr{mPendingSyncs.front().get()}) {
82 const auto res = sync->ClientWaitSync(0, 0);
83 switch (res) {
84 case ClientWaitSyncResult::WAIT_FAILED:
85 case ClientWaitSyncResult::TIMEOUT_EXPIRED:
86 return;
87 case ClientWaitSyncResult::CONDITION_SATISFIED:
88 case ClientWaitSyncResult::ALREADY_SIGNALED:
89 // Communication back to child happens in sync->lientWaitSync.
90 break;
93 mPendingSyncs.pop_front();
97 } // namespace mozilla