}
+bool QQuickWindowPrivate::emitError(QQuickWindow::SceneGraphError error, const QString &msg)
+{
+ Q_Q(QQuickWindow);
+ static const QMetaMethod errorSignal = QMetaMethod::fromSignal(&QQuickWindow::sceneGraphError);
+ if (q->isSignalConnected(errorSignal)) {
+ emit q->sceneGraphError(error, msg);
+ return true;
+ }
+ return false;
+}
+
void QQuickWindow::maybeUpdate()
{
Q_D(QQuickWindow);
*/
/*!
+ \fn void QQuickWindow::sceneGraphError(SceneGraphError error, const QString &message)
+
+ This signal is emitted when an error occurred during scene graph initialization.
+
+ Applications should connect to this signal if they wish to handle errors,
+ like OpenGL context creation failures, in a custom way. When no slot is
+ connected to the signal, the behavior will be different: Quick will print
+ the message, or show a message box, and terminate the application.
+
+ This signal will be emitted from the gui thread.
+
+ \since 5.3
+ */
+
+/*!
\class QQuickCloseEvent
\internal
\since 5.1
*/
/*!
+ \enum QQuickWindow::SceneGraphError
+
+ This enum describes the error in a sceneGraphError() signal.
+
+ \value ContextNotAvailable OpenGL context creation failed. This typically means that
+ no suitable OpenGL implementation was found, for example because no graphics drivers
+ are installed and so no OpenGL 2 support is present. On mobile and embedded boards
+ that use OpenGL ES such an error is likely to indicate issues in the windowing system
+ integration and possibly an incorrect configuration of Qt.
+
+ \since 5.3
+ */
+
+/*!
\fn void QQuickWindow::beforeSynchronizing()
This signal is emitted before the scene graph is synchronized with the QML state.
Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption)
+ enum SceneGraphError {
+ ContextNotAvailable = 1
+ };
+ Q_ENUMS(SceneGraphError)
+
QQuickWindow(QWindow *parent = 0);
virtual ~QQuickWindow();
Q_REVISION(1) void closing(QQuickCloseEvent *close);
void colorChanged(const QColor &);
Q_REVISION(1) void activeFocusItemChanged();
+ void sceneGraphError(QQuickWindow::SceneGraphError error, const QString &message);
public Q_SLOTS:
void update();
bool isRenderable() const;
+ bool emitError(QQuickWindow::SceneGraphError error, const QString &msg);
+
QQuickItem::UpdatePaintNodeData updatePaintNodeData;
QQuickItem *dirtyItemList;
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES
win32-msvc*:DEFINES *= _CRT_SECURE_NO_WARNINGS
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
+win32:!wince:!winrt: LIBS += -luser32
exists("qqml_enable_gcov") {
QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -fno-elide-constructors
if (QSGContext::sharedOpenGLContext())
gl->setShareContext(QSGContext::sharedOpenGLContext());
if (!gl->create()) {
- qWarning("QtQuick: failed to create OpenGL context");
delete gl;
gl = 0;
+ QString formatStr;
+ QDebug(&formatStr) << window->requestedFormat();
+ QString contextType = QLatin1String(QOpenGLFunctions::isES() ? "EGL" : "OpenGL");
+ const char *msg = QT_TRANSLATE_NOOP("QSGGuiThreadRenderLoop", "Failed to create %1 context for format %2");
+ QString translatedMsg = tr(msg).arg(contextType).arg(formatStr);
+ QString nonTranslatedMsg = QString(QLatin1String(msg)).arg(contextType).arg(formatStr);
+ bool signalEmitted = QQuickWindowPrivate::get(window)->emitError(QQuickWindow::ContextNotAvailable,
+ translatedMsg);
+ if (!signalEmitted)
+ qFatal("%s", qPrintable(nonTranslatedMsg));
} else {
current = gl->makeCurrent(window);
}
if (!w->thread->gl->create()) {
delete w->thread->gl;
w->thread->gl = 0;
- qWarning("QtQuick: failed to create OpenGL context");
+ QString formatStr;
+ QDebug(&formatStr) << w->window->requestedFormat();
+ QString contextType = QLatin1String(QOpenGLFunctions::isES() ? "EGL" : "OpenGL");
+ const char *msg = QT_TRANSLATE_NOOP("QSGThreadedRenderLoop",
+ "Failed to create %1 context for format %2");
+ QString translatedMsg = tr(msg).arg(contextType).arg(formatStr);
+ QString nonTranslatedMsg = QString(QLatin1String(msg)).arg(contextType).arg(formatStr);
+ bool signalEmitted = QQuickWindowPrivate::get(w->window)->emitError(QQuickWindow::ContextNotAvailable,
+ translatedMsg);
+ if (!signalEmitted)
+ qFatal("%s", qPrintable(nonTranslatedMsg));
return;
}
#include "qsgwindowsrenderloop_p.h"
#include <QtCore/QCoreApplication>
+#include <QtCore/QLibraryInfo>
#include <QtGui/QScreen>
#include <QtGui/QGuiApplication>
m_gl->setShareContext(QSGContext::sharedOpenGLContext());
bool created = m_gl->create();
if (!created) {
- qWarning("QtQuick: failed to create OpenGL context");
+ const bool isDebug = QLibraryInfo::isDebugBuild();
+ QString eglLibName = QLatin1String(isDebug ? "libEGLd.dll" : "libEGL.dll");
+ QString glesLibName = QLatin1String(isDebug ? "libGLESv2d.dll" : "libGLESv2.dll");
+ QString contextType = QLatin1String(QOpenGLFunctions::isES() ? "EGL" : "OpenGL");
+ const char *msg = QT_TRANSLATE_NOOP(
+ "QSGWindowsRenderLoop",
+ "Failed to create %1 context. "
+ "This is most likely caused by not having the necessary graphics drivers installed.\n\n"
+ "Install a driver providing OpenGL 2.0 or higher, or, if this is not possible, "
+ "make sure the Angle Open GL ES 2.0 emulation libraries (%2, %3 and d3dcompiler_*.dll) "
+ "are available in the application executable's directory or in a location listed in PATH.");
+ QString translatedMsg = tr(msg).arg(contextType).arg(eglLibName).arg(glesLibName);
+ QString nonTranslatedMsg = QString(QLatin1String(msg)).arg(contextType).arg(eglLibName).arg(glesLibName);
+ // If there is a slot connected to the error signal, emit it and leave it to
+ // the application to do something with the message. If nothing is connected,
+ // show a message on our own and terminate.
+ bool signalEmitted = QQuickWindowPrivate::get(window)->emitError(QQuickWindow::ContextNotAvailable,
+ translatedMsg);
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+ if (!signalEmitted && !isDebug && !GetConsoleWindow()) {
+ MessageBox(0, (LPCTSTR) translatedMsg.utf16(),
+ (LPCTSTR)(QCoreApplication::applicationName().utf16()),
+ MB_OK | MB_ICONERROR);
+ }
+#endif // !Q_OS_WINCE && !Q_OS_WINRT
delete m_gl;
m_gl = 0;
+ if (!signalEmitted)
+ qFatal("%s", qPrintable(nonTranslatedMsg));
return;
}
QSG_RENDER_TIMING_SAMPLE(time_created);