OpenGL: Move ExecutionQueue logic to the Queue.

No functional changes intended.

Bug: dawn:1413
Change-Id: I21b47898ea5a2564cafd4b0394c638bfd8e4ac45
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/140220
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/native/opengl/DeviceGL.cpp b/src/dawn/native/opengl/DeviceGL.cpp
index 2304b32..06f895c 100644
--- a/src/dawn/native/opengl/DeviceGL.cpp
+++ b/src/dawn/native/opengl/DeviceGL.cpp
@@ -27,8 +27,9 @@
 
 #include "dawn/native/opengl/DeviceGL.h"
 
-#include "dawn/common/Log.h"
+#include <utility>
 
+#include "dawn/common/Log.h"
 #include "dawn/native/BackendConnection.h"
 #include "dawn/native/ErrorData.h"
 #include "dawn/native/Instance.h"
@@ -140,9 +141,12 @@
 }
 
 MaybeError Device::Initialize(const DeviceDescriptor* descriptor) {
-    const OpenGLFunctions& gl = GetGL();
+    // Directly set the context current and use mGL instead of calling GetGL as GetGL will notify
+    // the (yet inexistent) queue that GL was used.
+    mContext->MakeCurrent();
+    const OpenGLFunctions& gl = mGL;
 
-    mFormatTable = BuildGLFormatTable(GetBGRAInternalFormat());
+    mFormatTable = BuildGLFormatTable(GetBGRAInternalFormat(gl));
 
     // Use the debug output functionality to get notified about GL errors
     // TODO(crbug.com/dawn/1475): add support for the KHR_debug and ARB_debug_output
@@ -185,7 +189,9 @@
     }
     gl.Enable(GL_SAMPLE_MASK);
 
-    return DeviceBase::Initialize(AcquireRef(new Queue(this, &descriptor->defaultQueue)));
+    Ref<Queue> queue;
+    DAWN_TRY_ASSIGN(queue, Queue::Create(this, &descriptor->defaultQueue));
+    return DeviceBase::Initialize(std::move(queue));
 }
 
 const GLFormat& Device::GetGLFormat(const Format& format) {
@@ -197,8 +203,7 @@
     return result;
 }
 
-GLenum Device::GetBGRAInternalFormat() const {
-    const OpenGLFunctions& gl = GetGL();
+GLenum Device::GetBGRAInternalFormat(const OpenGLFunctions& gl) const {
     if (gl.IsGLExtensionSupported("GL_EXT_texture_format_BGRA8888") ||
         gl.IsGLExtensionSupported("GL_APPLE_texture_format_BGRA8888")) {
         return GL_BGRA8_EXT;
@@ -272,20 +277,6 @@
     return usages;
 }
 
-void Device::SubmitFenceSync() {
-    if (!mHasPendingCommands) {
-        return;
-    }
-
-    const OpenGLFunctions& gl = GetGL();
-    GLsync sync = gl.FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-    GetQueue()->IncrementLastSubmittedCommandSerial();
-    mFencesInFlight.emplace(sync, GetLastSubmittedCommandSerial());
-
-    // Reset mHasPendingCommands after GetGL() which will set mHasPendingCommands to true.
-    mHasPendingCommands = false;
-}
-
 MaybeError Device::ValidateTextureCanBeWrapped(const TextureDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->dimension != wgpu::TextureDimension::e2D,
                     "Texture dimension (%s) is not %s.", descriptor->dimension,
@@ -306,6 +297,7 @@
 
     return {};
 }
+
 TextureBase* Device::CreateTextureWrappingEGLImage(const ExternalImageDescriptor* descriptor,
                                                    ::EGLImage image) {
     const OpenGLFunctions& gl = GetGL();
@@ -384,39 +376,10 @@
 }
 
 MaybeError Device::TickImpl() {
-    SubmitFenceSync();
+    ToBackend(GetQueue())->SubmitFenceSync();
     return {};
 }
 
-ResultOrError<ExecutionSerial> Device::CheckAndUpdateCompletedSerials() {
-    ExecutionSerial fenceSerial{0};
-    const OpenGLFunctions& gl = GetGL();
-    while (!mFencesInFlight.empty()) {
-        auto [sync, tentativeSerial] = mFencesInFlight.front();
-
-        // Fence are added in order, so we can stop searching as soon
-        // as we see one that's not ready.
-
-        // TODO(crbug.com/dawn/633): Remove this workaround after the deadlock issue is fixed.
-        if (IsToggleEnabled(Toggle::FlushBeforeClientWaitSync)) {
-            gl.Flush();
-        }
-        GLenum result = gl.ClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
-        if (result == GL_TIMEOUT_EXPIRED) {
-            return fenceSerial;
-        }
-        // Update fenceSerial since fence is ready.
-        fenceSerial = tentativeSerial;
-
-        gl.DeleteSync(sync);
-
-        mFencesInFlight.pop();
-
-        DAWN_ASSERT(fenceSerial > GetQueue()->GetCompletedCommandSerial());
-    }
-    return fenceSerial;
-}
-
 MaybeError Device::CopyFromStagingToBufferImpl(BufferBase* source,
                                                uint64_t sourceOffset,
                                                BufferBase* destination,
@@ -436,19 +399,6 @@
     DAWN_ASSERT(GetState() == State::Disconnected);
 }
 
-MaybeError Device::WaitForIdleForDestruction() {
-    const OpenGLFunctions& gl = GetGL();
-    gl.Finish();
-    DAWN_TRY(GetQueue()->CheckPassedSerials());
-    DAWN_ASSERT(mFencesInFlight.empty());
-
-    return {};
-}
-
-bool Device::HasPendingCommands() const {
-    return mHasPendingCommands;
-}
-
 uint32_t Device::GetOptimalBytesPerRowAlignment() const {
     return 1;
 }
@@ -461,13 +411,9 @@
     return 1.0f;
 }
 
-void Device::ForceEventualFlushOfCommands() {}
-
 const OpenGLFunctions& Device::GetGL() const {
-    if (mContext) {
-        mContext->MakeCurrent();
-    }
-    mHasPendingCommands = true;
+    mContext->MakeCurrent();
+    ToBackend(GetQueue())->OnGLUsed();
     return mGL;
 }
 
diff --git a/src/dawn/native/opengl/DeviceGL.h b/src/dawn/native/opengl/DeviceGL.h
index 179814e..b4aefc4 100644
--- a/src/dawn/native/opengl/DeviceGL.h
+++ b/src/dawn/native/opengl/DeviceGL.h
@@ -29,8 +29,6 @@
 #define SRC_DAWN_NATIVE_OPENGL_DEVICEGL_H_
 
 #include <memory>
-#include <queue>
-#include <utility>
 
 #include "dawn/native/dawn_platform.h"
 
@@ -68,8 +66,6 @@
 
     const GLFormat& GetGLFormat(const Format& format);
 
-    void SubmitFenceSync();
-
     MaybeError ValidateTextureCanBeWrapped(const TextureDescriptor* descriptor);
     TextureBase* CreateTextureWrappingEGLImage(const ExternalImageDescriptor* descriptor,
                                                ::EGLImage image);
@@ -104,12 +100,6 @@
         virtual void MakeCurrent() = 0;
     };
 
-    // TODO(dawn:1413) move these methods to the opengl::Queue.
-    void ForceEventualFlushOfCommands();
-    bool HasPendingCommands() const;
-    ResultOrError<ExecutionSerial> CheckAndUpdateCompletedSerials();
-    MaybeError WaitForIdleForDestruction();
-
   private:
     Device(AdapterBase* adapter,
            const DeviceDescriptor* descriptor,
@@ -147,17 +137,13 @@
     ResultOrError<wgpu::TextureUsage> GetSupportedSurfaceUsageImpl(
         const Surface* surface) const override;
 
-    GLenum GetBGRAInternalFormat() const;
+    GLenum GetBGRAInternalFormat(const OpenGLFunctions& gl) const;
     void DestroyImpl() override;
 
     const OpenGLFunctions mGL;
 
-    std::queue<std::pair<GLsync, ExecutionSerial>> mFencesInFlight;
-
     GLFormatTable mFormatTable;
     std::unique_ptr<Context> mContext = nullptr;
-    // Has pending GL commands which are not associated with a fence.
-    mutable bool mHasPendingCommands = false;
 };
 
 }  // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/QueueGL.cpp b/src/dawn/native/opengl/QueueGL.cpp
index 01dd8c0..1bce293 100644
--- a/src/dawn/native/opengl/QueueGL.cpp
+++ b/src/dawn/native/opengl/QueueGL.cpp
@@ -36,6 +36,10 @@
 
 namespace dawn::native::opengl {
 
+ResultOrError<Ref<Queue>> Queue::Create(Device* device, const QueueDescriptor* descriptor) {
+    return AcquireRef(new Queue(device, descriptor));
+}
+
 Queue::Queue(Device* device, const QueueDescriptor* descriptor) : QueueBase(device, descriptor) {}
 
 MaybeError Queue::SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) {
@@ -87,20 +91,67 @@
     return {};
 }
 
+void Queue::OnGLUsed() {
+    mHasPendingCommands = true;
+}
+
+void Queue::SubmitFenceSync() {
+    if (!mHasPendingCommands) {
+        return;
+    }
+
+    const OpenGLFunctions& gl = ToBackend(GetDevice())->GetGL();
+    GLsync sync = gl.FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+    IncrementLastSubmittedCommandSerial();
+    mFencesInFlight.emplace(sync, GetLastSubmittedCommandSerial());
+    mHasPendingCommands = false;
+}
+
 bool Queue::HasPendingCommands() const {
-    return ToBackend(GetDevice())->HasPendingCommands();
+    return mHasPendingCommands;
 }
 
 ResultOrError<ExecutionSerial> Queue::CheckAndUpdateCompletedSerials() {
-    return ToBackend(GetDevice())->CheckAndUpdateCompletedSerials();
+    const Device* device = ToBackend(GetDevice());
+    const OpenGLFunctions& gl = device->GetGL();
+
+    ExecutionSerial fenceSerial{0};
+    while (!mFencesInFlight.empty()) {
+        auto [sync, tentativeSerial] = mFencesInFlight.front();
+
+        // Fence are added in order, so we can stop searching as soon
+        // as we see one that's not ready.
+
+        // TODO(crbug.com/dawn/633): Remove this workaround after the deadlock issue is fixed.
+        if (device->IsToggleEnabled(Toggle::FlushBeforeClientWaitSync)) {
+            gl.Flush();
+        }
+        GLenum result = gl.ClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
+        if (result == GL_TIMEOUT_EXPIRED) {
+            return fenceSerial;
+        }
+        // Update fenceSerial since fence is ready.
+        fenceSerial = tentativeSerial;
+
+        gl.DeleteSync(sync);
+
+        mFencesInFlight.pop();
+
+        DAWN_ASSERT(fenceSerial > GetCompletedCommandSerial());
+    }
+    return fenceSerial;
 }
 
 void Queue::ForceEventualFlushOfCommands() {
-    return ToBackend(GetDevice())->ForceEventualFlushOfCommands();
+    mHasPendingCommands = true;
 }
 
 MaybeError Queue::WaitForIdleForDestruction() {
-    return ToBackend(GetDevice())->WaitForIdleForDestruction();
+    const OpenGLFunctions& gl = ToBackend(GetDevice())->GetGL();
+    gl.Finish();
+    DAWN_TRY(CheckPassedSerials());
+    DAWN_ASSERT(mFencesInFlight.empty());
+    return {};
 }
 
 }  // namespace dawn::native::opengl
diff --git a/src/dawn/native/opengl/QueueGL.h b/src/dawn/native/opengl/QueueGL.h
index 40aef31..1260907 100644
--- a/src/dawn/native/opengl/QueueGL.h
+++ b/src/dawn/native/opengl/QueueGL.h
@@ -28,7 +28,11 @@
 #ifndef SRC_DAWN_NATIVE_OPENGL_QUEUEGL_H_
 #define SRC_DAWN_NATIVE_OPENGL_QUEUEGL_H_
 
+#include <queue>
+#include <utility>
+
 #include "dawn/native/Queue.h"
+#include "dawn/native/opengl/opengl_platform.h"
 
 namespace dawn::native::opengl {
 
@@ -36,9 +40,14 @@
 
 class Queue final : public QueueBase {
   public:
-    Queue(Device* device, const QueueDescriptor* descriptor);
+    static ResultOrError<Ref<Queue>> Create(Device* device, const QueueDescriptor* descriptor);
+
+    void OnGLUsed();
+    void SubmitFenceSync();
 
   private:
+    Queue(Device* device, const QueueDescriptor* descriptor);
+
     MaybeError SubmitImpl(uint32_t commandCount, CommandBufferBase* const* commands) override;
     MaybeError WriteBufferImpl(BufferBase* buffer,
                                uint64_t bufferOffset,
@@ -53,6 +62,11 @@
     ResultOrError<ExecutionSerial> CheckAndUpdateCompletedSerials() override;
     void ForceEventualFlushOfCommands() override;
     MaybeError WaitForIdleForDestruction() override;
+
+    std::queue<std::pair<GLsync, ExecutionSerial>> mFencesInFlight;
+
+    // Has pending GL commands which are not associated with a fence.
+    bool mHasPendingCommands = false;
 };
 
 }  // namespace dawn::native::opengl