28
void printOpenGLESConfig() {
29
static bool once = true;
31
const char* string = (const char*) glGetString(GL_VENDOR);
32
qCDebug(ubuntumirclient, "OpenGL ES vendor: %s", string);
33
string = (const char*) glGetString(GL_RENDERER);
34
qCDebug(ubuntumirclient, "OpenGL ES renderer: %s", string);
35
string = (const char*) glGetString(GL_VERSION);
36
qCDebug(ubuntumirclient, "OpenGL ES version: %s", string);
37
string = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
38
qCDebug(ubuntumirclient, "OpenGL ES Shading Language version: %s", string);
39
string = (const char*) glGetString(GL_EXTENSIONS);
40
qCDebug(ubuntumirclient, "OpenGL ES extensions: %s", string);
45
void printEglConfig(EGLDisplay display, EGLConfig config) {
28
void printEglConfig(EGLDisplay display, EGLConfig config)
46
30
Q_ASSERT(display != EGL_NO_DISPLAY);
47
31
Q_ASSERT(config != nullptr);
49
static const struct { const EGLint attrib; const char* name; } kAttribs[] = {
50
{ EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" },
51
{ EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" },
52
{ EGL_BLUE_SIZE, "EGL_BLUE_SIZE" },
53
{ EGL_GREEN_SIZE, "EGL_GREEN_SIZE" },
54
{ EGL_RED_SIZE, "EGL_RED_SIZE" },
55
{ EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" },
56
{ EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" },
57
{ EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" },
58
{ EGL_CONFIG_ID, "EGL_CONFIG_ID" },
59
{ EGL_LEVEL, "EGL_LEVEL" },
60
{ EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" },
61
{ EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" },
62
{ EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" },
63
{ EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" },
64
{ EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" },
65
{ EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" },
66
{ EGL_SAMPLES, "EGL_SAMPLES" },
67
{ EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" },
68
{ EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" },
69
{ EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" },
70
{ EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" },
71
{ EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" },
72
{ EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" },
73
{ EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" },
74
{ EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" },
75
{ EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" },
76
{ EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" },
79
const char* string = eglQueryString(display, EGL_VENDOR);
33
const char *string = eglQueryString(display, EGL_VENDOR);
80
34
qCDebug(ubuntumirclient, "EGL vendor: %s", string);
82
36
string = eglQueryString(display, EGL_VERSION);
85
39
string = eglQueryString(display, EGL_EXTENSIONS);
86
40
qCDebug(ubuntumirclient, "EGL extensions: %s", string);
88
qCDebug(ubuntumirclient, "EGL configuration attibutes:");
89
for (int index = 0; kAttribs[index].attrib != -1; index++) {
91
if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value))
92
qCDebug(ubuntumirclient, " %s: %d", kAttribs[index].name, static_cast<int>(value));
96
QString eglErrorToString(EGLint errorNumber)
98
#define EGL_ERROR_CASE(error) case error: return QString(#error);
100
switch (errorNumber) {
101
EGL_ERROR_CASE(EGL_SUCCESS)
102
EGL_ERROR_CASE(EGL_NOT_INITIALIZED)
103
EGL_ERROR_CASE(EGL_BAD_ACCESS)
104
EGL_ERROR_CASE(EGL_BAD_ALLOC)
105
EGL_ERROR_CASE(EGL_BAD_ATTRIBUTE)
106
EGL_ERROR_CASE(EGL_BAD_CONTEXT)
107
EGL_ERROR_CASE(EGL_BAD_CONFIG)
108
EGL_ERROR_CASE(EGL_BAD_CURRENT_SURFACE)
109
EGL_ERROR_CASE(EGL_BAD_DISPLAY)
110
EGL_ERROR_CASE(EGL_BAD_SURFACE)
111
EGL_ERROR_CASE(EGL_BAD_MATCH)
112
EGL_ERROR_CASE(EGL_BAD_PARAMETER)
113
EGL_ERROR_CASE(EGL_BAD_NATIVE_PIXMAP)
114
EGL_ERROR_CASE(EGL_BAD_NATIVE_WINDOW)
115
EGL_ERROR_CASE(EGL_CONTEXT_LOST)
120
#undef EGL_ERROR_CASE
125
#ifdef QTUBUNTU_USE_OPENGL
126
return EGL_OPENGL_API;
128
return EGL_OPENGL_ES_API;
132
const int kSwapInterval = 1;
134
int qGetEnvIntValue(const char *varName, bool *ok)
136
return qgetenv(varName).toInt(ok);
42
qCDebug(ubuntumirclient, "EGL configuration attributes:");
43
q_printEglConfig(display, config);
139
46
} // anonymous namespace
141
UbuntuOpenGLContext::UbuntuOpenGLContext(const QSurfaceFormat &surfaceFormat, UbuntuOpenGLContext *share,
142
EGLDisplay display, EGLConfig config)
143
: mSurfaceFormat(surfaceFormat)
144
, mEglDisplay(display)
48
UbuntuOpenGLContext::UbuntuOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
50
: QEGLPlatformContext(format, share, display, 0)
146
// Create an OpenGL ES 2 context.
147
QVector<EGLint> attribs;
148
attribs.append(EGL_CONTEXT_CLIENT_VERSION);
150
attribs.append(EGL_NONE);
151
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
153
52
if (ubuntumirclient().isDebugEnabled()) {
154
printEglConfig(mEglDisplay, config);
53
printEglConfig(display, eglConfig());
157
// Set vblank swap interval.
159
int swapInterval = qGetEnvIntValue("QTUBUNTU_SWAPINTERVAL", &ok);
161
swapInterval = kSwapInterval;
163
qCDebug(ubuntumirclient, "Setting swap interval to %d", swapInterval);
164
eglSwapInterval(mEglDisplay, swapInterval);
166
mEglContext = eglCreateContext(mEglDisplay, config, share ? share->eglContext() : EGL_NO_CONTEXT,
167
attribs.constData());
169
Q_ASSERT(mEglContext != EGL_NO_CONTEXT);
172
UbuntuOpenGLContext::~UbuntuOpenGLContext()
174
ASSERT(eglDestroyContext(mEglDisplay, mEglContext) == EGL_TRUE);
177
57
static bool needsFBOReadBackWorkaround()
203
83
return offscreen->buffer()->bind();
205
EGLSurface eglSurface = static_cast<UbuntuWindow*>(surface)->eglSurface();
206
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
208
EGLBoolean result = eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
209
if (result == EGL_FALSE) {
210
qCCritical(ubuntumirclient, "eglMakeCurrent() failed with %s",
211
qPrintable(eglErrorToString(eglGetError())));
215
QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
216
if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) {
217
ctx_d->workaround_brokenFBOReadBack = true;
220
if (ubuntumirclient().isDebugEnabled()) {
221
printOpenGLESConfig();
85
const bool ret = QEGLPlatformContext::makeCurrent(surface);
88
QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
89
if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) {
90
ctx_d->workaround_brokenFBOReadBack = true;
227
void UbuntuOpenGLContext::doneCurrent()
98
// Following method used internally in the base class QEGLPlatformContext to access
99
// the egl surface of a QPlatformSurface/UbuntuWindow
100
EGLSurface UbuntuOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
229
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
230
ASSERT(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_TRUE);
102
auto ubuntuWindow = static_cast<UbuntuWindow *>(surface);
103
return ubuntuWindow->eglSurface();
233
void UbuntuOpenGLContext::swapBuffers(QPlatformSurface* surface)
106
void UbuntuOpenGLContext::swapBuffers(QPlatformSurface *surface)
235
UbuntuWindow *ubuntuWindow = static_cast<UbuntuWindow*>(surface);
237
EGLSurface eglSurface = ubuntuWindow->eglSurface();
238
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
239
ASSERT(eglSwapBuffers(mEglDisplay, eglSurface) == EGL_TRUE);
108
QEGLPlatformContext::swapBuffers(surface);
110
// notify window on swap completion
111
auto ubuntuWindow = static_cast<UbuntuWindow *>(surface);
241
112
ubuntuWindow->onSwapBuffersDone();
244
void (*UbuntuOpenGLContext::getProcAddress(const QByteArray& procName)) ()
246
ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
247
return eglGetProcAddress(procName.constData());