1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWebEngine module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39
40 #include "compositor_resource_fence.h"
41 #include "ozone/gl_surface_qt.h"
42 #include "ui/gl/gl_context.h"
43
44 #include <QtGui/private/qtguiglobal_p.h>
45 #include <QtGui/qopenglcontext.h>
46
47 #ifndef GL_TIMEOUT_IGNORED
48 #define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
49 #endif
50
51
52 #if QT_CONFIG(egl)
53 #include <EGL/egl.h>
54 #include <EGL/eglext.h>
55 #endif
56
57 namespace QtWebEngineCore {
58
wait()59 void CompositorResourceFence::wait()
60 {
61 if (!m_sync)
62 return;
63
64 QOpenGLContext *context = QOpenGLContext::currentContext();
65 Q_ASSERT(context);
66
67 // Chromium uses its own GL bindings and stores in in thread local storage.
68 // For that reason, let chromium_gpu_helper.cpp contain the producing code that will run in the Chromium
69 // GPU thread, and put the sync consuming code here that will run in the QtQuick SG or GUI thread.
70 switch (m_sync.type) {
71 case gl::TransferableFence::NoSync:
72 break;
73 case gl::TransferableFence::EglSync:
74 #ifdef EGL_KHR_reusable_sync
75 {
76 static bool resolved = false;
77 static PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR = 0;
78
79 if (!resolved) {
80 if (gl::GLSurfaceQt::HasEGLExtension("EGL_KHR_fence_sync"))
81 eglClientWaitSyncKHR = (PFNEGLCLIENTWAITSYNCKHRPROC)context->getProcAddress("eglClientWaitSyncKHR");
82 resolved = true;
83 }
84
85 if (eglClientWaitSyncKHR)
86 // FIXME: Use the less wasteful eglWaitSyncKHR once we have a device that supports EGL_KHR_wait_sync.
87 eglClientWaitSyncKHR(m_sync.egl.display, m_sync.egl.sync, 0, EGL_FOREVER_KHR);
88 }
89 #endif
90 break;
91 case gl::TransferableFence::ArbSync:
92 typedef void (QOPENGLF_APIENTRYP WaitSyncPtr)(GLsync sync, GLbitfield flags, GLuint64 timeout);
93 static WaitSyncPtr glWaitSync_ = 0;
94 if (!glWaitSync_) {
95 glWaitSync_ = (WaitSyncPtr)context->getProcAddress("glWaitSync");
96 Q_ASSERT(glWaitSync_);
97 }
98 glWaitSync_(m_sync.arb.sync, 0, GL_TIMEOUT_IGNORED);
99 break;
100 }
101
102 release();
103 }
104
release()105 void CompositorResourceFence::release()
106 {
107 if (!m_sync)
108 return;
109
110 QOpenGLContext *context = QOpenGLContext::currentContext();
111 if (!context)
112 return;
113
114 // Chromium uses its own GL bindings and stores in in thread local storage.
115 // For that reason, let chromium_gpu_helper.cpp contain the producing code that will run in the Chromium
116 // GPU thread, and put the sync consuming code here that will run in the QtQuick SG or GUI thread.
117 switch (m_sync.type) {
118 case gl::TransferableFence::NoSync:
119 break;
120 case gl::TransferableFence::EglSync:
121 #ifdef EGL_KHR_reusable_sync
122 {
123 static bool resolved = false;
124 static PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = 0;
125
126 if (!resolved) {
127 if (gl::GLSurfaceQt::HasEGLExtension("EGL_KHR_fence_sync"))
128 eglDestroySyncKHR = (PFNEGLDESTROYSYNCKHRPROC)context->getProcAddress("eglDestroySyncKHR");
129 resolved = true;
130 }
131
132 if (eglDestroySyncKHR) {
133 // FIXME: Use the less wasteful eglWaitSyncKHR once we have a device that supports EGL_KHR_wait_sync.
134 eglDestroySyncKHR(m_sync.egl.display, m_sync.egl.sync);
135 m_sync.reset();
136 }
137 }
138 #endif
139 break;
140 case gl::TransferableFence::ArbSync:
141 typedef void (QOPENGLF_APIENTRYP DeleteSyncPtr)(GLsync sync);
142 static DeleteSyncPtr glDeleteSync_ = 0;
143 if (!glDeleteSync_) {
144 glDeleteSync_ = (DeleteSyncPtr)context->getProcAddress("glDeleteSync");
145 Q_ASSERT(glDeleteSync_);
146 }
147 glDeleteSync_(m_sync.arb.sync);
148 m_sync.reset();
149 break;
150 }
151 // If Chromium was able to create a sync, we should have been able to handle its type here too.
152 Q_ASSERT(!m_sync);
153 }
154
155 // static
create(std::unique_ptr<gl::GLFence> glFence)156 scoped_refptr<CompositorResourceFence> CompositorResourceFence::create(std::unique_ptr<gl::GLFence> glFence)
157 {
158 if (!glFence && gl::GLContext::GetCurrent() && gl::GLFence::IsSupported())
159 glFence = gl::GLFence::Create();
160 if (glFence)
161 return base::MakeRefCounted<CompositorResourceFence>(glFence->Transfer());
162 return nullptr;
163 }
164
165 } // namespace QtWebEngineCore
166