Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qandroidplatformopenglwindow.cpp
Go to the documentation of this file.
1// Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
2// Copyright (C) 2016 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
6
10
11#include <QSurfaceFormat>
12#include <QtGui/private/qwindow_p.h>
13#include <QtGui/qguiapplication.h>
14
15#include <QtGui/private/qeglconvenience_p.h>
16#include <android/native_window.h>
17#include <android/native_window_jni.h>
18#include <qpa/qplatformscreen.h>
19#include <qpa/qwindowsysteminterface.h>
20
22
23QAndroidPlatformOpenGLWindow::QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display)
24 :QAndroidPlatformWindow(window), m_eglDisplay(display)
25{ }
26
27QAndroidPlatformOpenGLWindow::~QAndroidPlatformOpenGLWindow()
28{
29 m_surfaceWaitCondition.wakeOne();
30 lockSurface();
31 destroySurface();
32 clearSurface();
33 unlockSurface();
34}
35
36void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
37{
38 QAndroidPlatformWindow::setGeometry(rect);
39
40 QRect availableGeometry = screen()->availableGeometry();
41 if (rect.width() > 0
42 && rect.height() > 0
43 && availableGeometry.width() > 0
44 && availableGeometry.height() > 0) {
45 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
46 }
47}
48
49// Called by QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(),
50// surface is already locked when calling this
51EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
52{
53 if (QAndroidEventDispatcherStopper::stopped() ||
54 QGuiApplication::applicationState() == Qt::ApplicationSuspended) {
55 qCDebug(lcQpaWindow) << "Application not active, return existing surface.";
56 return m_eglSurface;
57 }
58 // If we haven't called createSurface() yet, call it and wait until Android has created
59 // the Surface
61 static constexpr char funcName[] = "QAndroidPlatformOpenGLWindow::eglSurface()";
62 QtAndroidPrivate::AndroidDeadlockProtector protector(funcName);
63 if (!protector.acquire()) {
64 qFatal("Failed to acquire deadlock protector for %s.", funcName);
65 return m_eglSurface;
66 }
67
69 qCDebug(lcQpaWindow) << "called createSurface(), waiting for Surface to be ready...";
70 m_surfaceWaitCondition.wait(&m_surfaceMutex);
71 }
72
73 if (m_eglSurface == EGL_NO_SURFACE)
74 ensureEglSurfaceCreated(config);
75
76 return m_eglSurface;
77}
78
79void QAndroidPlatformOpenGLWindow::applicationStateChanged(Qt::ApplicationState state)
80{
81 QAndroidPlatformWindow::applicationStateChanged(state);
82 if (state <= Qt::ApplicationHidden) {
85 clearSurface();
87 }
88}
89
90// m_surfaceMutex already locked, called only by eglSurface()
91// and QAndroidPlatformOpenGLContext::swapBuffers().
92bool QAndroidPlatformOpenGLWindow::ensureEglSurfaceCreated(EGLConfig config)
93{
94 // Either no surface created, or the m_eglSurface already wraps the active Surface,
95 // so makeCurrent is NOT needed, and we should not create a new EGL surface.
96 if (!m_androidSurfaceCreated || !m_androidSurfaceObject.isValid()) {
97 qCDebug(lcQpaWindow) << "Skipping create egl on invalid or not yet created surface";
98 return false;
99 }
100
101 clearSurface();
102 m_nativeWindow = ANativeWindow_fromSurface(
103 QJniEnvironment::getJniEnv(), m_androidSurfaceObject.object());
104 m_androidSurfaceObject = QJniObject();
105 m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
106 m_format = q_glFormatFromConfig(m_eglDisplay, config, window()->requestedFormat());
107 if (Q_UNLIKELY(m_eglSurface == EGL_NO_SURFACE)) {
108 EGLint error = eglGetError();
109 eglTerminate(m_eglDisplay);
110 qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error);
111 }
112
113 // we've created another Surface, the window should be repainted
114 sendExpose();
115
116 return true;
117}
118
119QSurfaceFormat QAndroidPlatformOpenGLWindow::format() const
120{
121 if (m_nativeWindow == 0)
122 return window()->requestedFormat();
123
124 return m_format;
125}
126
127void QAndroidPlatformOpenGLWindow::clearSurface()
128{
129 if (m_eglSurface != EGL_NO_SURFACE) {
130 eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
131 eglDestroySurface(m_eglDisplay, m_eglSurface);
132 m_eglSurface = EGL_NO_SURFACE;
133 }
134
135 if (m_nativeWindow) {
136 ANativeWindow_release(m_nativeWindow);
137 m_nativeWindow = nullptr;
138 }
139}
140
141QT_END_NAMESPACE
\inmodule QtGui
Definition qwindow.h:63