1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins 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 #ifndef QWINDOWSEGLCONTEXT_H
41 #define QWINDOWSEGLCONTEXT_H
42 
43 #include "qwindowsopenglcontext.h"
44 #include "qwindowsopengltester.h"
45 #include <EGL/egl.h>
46 
47 QT_BEGIN_NAMESPACE
48 
49 struct QWindowsLibEGL
50 {
51     bool init();
52 
53     EGLint (EGLAPIENTRY * eglGetError)(void);
54     EGLDisplay (EGLAPIENTRY * eglGetDisplay)(EGLNativeDisplayType display_id);
55     EGLBoolean (EGLAPIENTRY * eglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
56     EGLBoolean (EGLAPIENTRY * eglTerminate)(EGLDisplay dpy);
57     EGLBoolean (EGLAPIENTRY * eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list,
58                                                EGLConfig *configs, EGLint config_size,
59                                                EGLint *num_config);
60     EGLBoolean (EGLAPIENTRY * eglGetConfigAttrib)(EGLDisplay dpy, EGLConfig config,
61                                                   EGLint attribute, EGLint *value);
62     EGLSurface (EGLAPIENTRY * eglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config,
63                                                       EGLNativeWindowType win,
64                                                       const EGLint *attrib_list);
65     EGLSurface (EGLAPIENTRY * eglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config,
66                                                        const EGLint *attrib_list);
67     EGLBoolean (EGLAPIENTRY * eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
68     EGLBoolean (EGLAPIENTRY * eglBindAPI)(EGLenum api);
69     EGLBoolean (EGLAPIENTRY * eglSwapInterval)(EGLDisplay dpy, EGLint interval);
70     EGLContext (EGLAPIENTRY * eglCreateContext)(EGLDisplay dpy, EGLConfig config,
71                                                 EGLContext share_context,
72                                                 const EGLint *attrib_list);
73     EGLBoolean (EGLAPIENTRY * eglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
74     EGLBoolean (EGLAPIENTRY * eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw,
75                                               EGLSurface read, EGLContext ctx);
76     EGLContext (EGLAPIENTRY * eglGetCurrentContext)(void);
77     EGLSurface (EGLAPIENTRY * eglGetCurrentSurface)(EGLint readdraw);
78     EGLDisplay (EGLAPIENTRY * eglGetCurrentDisplay)(void);
79     EGLBoolean (EGLAPIENTRY * eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
80     QFunctionPointer (EGLAPIENTRY *eglGetProcAddress)(const char *procname);
81 
82     EGLDisplay (EGLAPIENTRY * eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list);
83 
84 private:
85 #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC)
86     void *resolve(const char *name);
87     HMODULE m_lib;
88 #endif
89 };
90 
91 struct QWindowsLibGLESv2
92 {
93     bool init();
94 
95 #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC)
moduleHandleQWindowsLibGLESv296     void *moduleHandle() const { return m_lib; }
97 #else
moduleHandleQWindowsLibGLESv298     void *moduleHandle() const { return nullptr; }
99 #endif
100 
101     const GLubyte * (APIENTRY * glGetString)(GLenum name);
102 
103 #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC)
104     void *resolve(const char *name);
105 private:
106     HMODULE m_lib;
107 #endif
108 };
109 
110 class QWindowsEGLStaticContext : public QWindowsStaticOpenGLContext
111 {
112     Q_DISABLE_COPY_MOVE(QWindowsEGLStaticContext)
113 
114 public:
115     static QWindowsEGLStaticContext *create(QWindowsOpenGLTester::Renderers preferredType);
116     ~QWindowsEGLStaticContext() override;
117 
display()118     EGLDisplay display() const { return m_display; }
119 
120     QWindowsOpenGLContext *createContext(QOpenGLContext *context) override;
moduleHandle()121     void *moduleHandle() const override { return libGLESv2.moduleHandle(); }
moduleType()122     QOpenGLContext::OpenGLModuleType moduleType() const override { return QOpenGLContext::LibGLES; }
123 
124     void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) override;
125     void destroyWindowSurface(void *nativeSurface) override;
126 
127     QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat);
128 
129     static QWindowsLibEGL libEGL;
130     static QWindowsLibGLESv2 libGLESv2;
131 
132 private:
133     explicit QWindowsEGLStaticContext(EGLDisplay display);
134     static bool initializeAngle(QWindowsOpenGLTester::Renderers preferredType, HDC dc,
135                                 EGLDisplay *display, EGLint *major, EGLint *minor);
136 
137     const EGLDisplay m_display;
138 };
139 
140 class QWindowsEGLContext : public QWindowsOpenGLContext
141 {
142 public:
143     QWindowsEGLContext(QWindowsEGLStaticContext *staticContext,
144                        const QSurfaceFormat &format,
145                        QPlatformOpenGLContext *share);
146     ~QWindowsEGLContext() override;
147 
148     bool makeCurrent(QPlatformSurface *surface) override;
149     void doneCurrent() override;
150     void swapBuffers(QPlatformSurface *surface) override;
151     QFunctionPointer getProcAddress(const char *procName) override;
152 
format()153     QSurfaceFormat format() const override { return m_format; }
isSharing()154     bool isSharing() const override { return m_shareContext != EGL_NO_CONTEXT; }
isValid()155     bool isValid() const override { return m_eglContext != EGL_NO_CONTEXT; }
156 
nativeContext()157     void *nativeContext() const override { return m_eglContext; }
nativeDisplay()158     void *nativeDisplay() const override { return m_eglDisplay; }
nativeConfig()159     void *nativeConfig() const override { return m_eglConfig; }
160 
161 private:
162     EGLConfig chooseConfig(const QSurfaceFormat &format);
163 
164     QWindowsEGLStaticContext *m_staticContext;
165     EGLContext m_eglContext;
166     EGLContext m_shareContext;
167     EGLDisplay m_eglDisplay;
168     EGLConfig m_eglConfig;
169     QSurfaceFormat m_format;
170     EGLenum m_api = EGL_OPENGL_ES_API;
171     int m_swapInterval = -1;
172 };
173 
174 QT_END_NAMESPACE
175 
176 #endif // QWINDOWSEGLCONTEXT_H
177