diff options
author | Liang Qi <liang.qi@qt.io> | 2018-01-09 21:52:56 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-01-09 21:53:21 +0100 |
commit | 6035467b37bc71b0ea25155fa70f85bee054d1a3 (patch) | |
tree | c2787b12c73706f18e03c148eea6241dc43fdb97 | |
parent | 09bac2983badd9698bdfe499fd93d53364579876 (diff) | |
parent | bc8fefc2470ccb2ecc2edaab9822f71be09fa901 (diff) |
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts:
.qmake.conf
Change-Id: Ib0005461e6abb8dfeb4f9697df54421b00b67f03
-rw-r--r-- | qtwebglplugin.pro | 2 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/qwebglcontext.cpp | 157 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/qwebglcontext.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/qwebglfunctioncall.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/qwebglfunctioncall.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/qwebglintegration.cpp | 14 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/qwebglintegration_p.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/qwebglwebsocketserver.cpp | 75 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/qwebglwindow.cpp | 6 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/qwebglwindow.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/webqt.jsx | 237 |
11 files changed, 281 insertions, 225 deletions
diff --git a/qtwebglplugin.pro b/qtwebglplugin.pro index 51e803d..f16dfaf 100644 --- a/qtwebglplugin.pro +++ b/qtwebglplugin.pro @@ -1,3 +1,3 @@ -requires(!winrt:!watchos:qtHaveModule(websockets):qtHaveModule(gui)) +requires(!winrt:!watchos:qtHaveModule(websockets):qtHaveModule(gui):qtConfig(opengl)) load(qt_parts) diff --git a/src/plugins/platforms/webgl/qwebglcontext.cpp b/src/plugins/platforms/webgl/qwebglcontext.cpp index 5e92565..be62649 100644 --- a/src/plugins/platforms/webgl/qwebglcontext.cpp +++ b/src/plugins/platforms/webgl/qwebglcontext.cpp @@ -48,6 +48,7 @@ #include <QtWebSockets/qwebsocket.h> #include <cstring> +#include <limits> QT_BEGIN_NAMESPACE @@ -245,32 +246,42 @@ static void setVertexAttribs(QWebGLFunctionCall *event, GLsizei count) } } -template<class POINTER, class SIZE> -inline QWebGLFunctionCall *addHelper(QWebGLFunctionCall *e, const QPair<POINTER*, SIZE> &elements) +template<class POINTER, class COUNT> +inline QWebGLFunctionCall *addHelper(QWebGLFunctionCall *event, + const QPair<POINTER, COUNT> &elements) { - if (e) { - for (auto i = 0; i < elements.second; ++i) - e->add(elements.first[i]); - } - return e; + QVariantList list; + for (auto i = 0; i < elements.second; ++i) + list.append(QVariant::fromValue(elements.first[i])); + event->addList(list); + return event; +} + +template<class SIZE> +inline void addHelper(QWebGLFunctionCall *event, const QPair<const float *, SIZE> &elements) +{ + QVariantList list; + for (auto i = 0; i < elements.second; ++i) + list.append(QVariant::fromValue<double>(elements.first[i])); + event->addList(list); } template<class T> -inline QWebGLFunctionCall *addHelper(QWebGLFunctionCall *e, const T &value) +inline QWebGLFunctionCall *addHelper(QWebGLFunctionCall *event, const T &value) { - if (e) - e->add(value); - return e; + if (event) + event->add(value); + return event; } template<class T, class... Ts> -inline QWebGLFunctionCall *addHelper(QWebGLFunctionCall *e, const T &value, const Ts&... rest) +inline QWebGLFunctionCall *addHelper(QWebGLFunctionCall *event, const T &value, const Ts&... rest) { - if (e) { - e->add(value); - addHelper(e, rest...); + if (event) { + event->add(value); + addHelper(event, rest...); } - return e; + return event; } template<class T> @@ -286,9 +297,6 @@ static T queryValue(int id, const T &defaultValue = T()) return variant.value<T>(); } -struct GLFunction; -static QHash<QString, const GLFunction *> glFunctions; - template<typename T> struct ParameterTypeTraits { static int typeId() { return qMetaTypeId<T>(); } @@ -321,6 +329,8 @@ struct GLFunction bool isArray; }; + static QHash<QString, const GLFunction *> byName; + static QStringList remoteFunctionNames; using ParameterList = QVector<Parameter>; GLFunction(const QString &remoteName, @@ -330,19 +340,26 @@ struct GLFunction : remoteName(remoteName), localName(localName), functionPointer(functionPointer), parameters(parameters) { - Q_ASSERT(!glFunctions.contains(localName)); - glFunctions.insert(localName, this); + Q_ASSERT(!byName.contains(localName)); + byName.insert(localName, this); + id = remoteFunctionNames.size(); + Q_ASSERT(remoteFunctionNames.size() <= std::numeric_limits<quint8>::max()); + remoteFunctionNames.append(remoteName); + Q_ASSERT(byName.size() == remoteFunctionNames.size()); } GLFunction(const QString &name) : GLFunction(name, name, nullptr) {} - + quint8 id; const QString remoteName; const QString localName; const QFunctionPointer functionPointer; const ParameterList parameters; }; +QHash<QString, const GLFunction *> GLFunction::byName; +QStringList GLFunction::remoteFunctionNames; + template<const GLFunction *Function> static QWebGLFunctionCall *createEventImpl(bool wait) { @@ -354,7 +371,7 @@ static QWebGLFunctionCall *createEventImpl(bool wait) if (!clientData || !clientData->socket || clientData->socket->state() != QAbstractSocket::ConnectedState) return nullptr; - return new QWebGLFunctionCall(Function->remoteName, handle->currentSurface(), wait); + return new QWebGLFunctionCall(Function->localName, handle->currentSurface(), wait); } static void postEventImpl(QWebGLFunctionCall *event) @@ -623,7 +640,7 @@ QWEBGL_FUNCTION(deleteBuffers, void, glDeleteBuffers, QWEBGL_FUNCTION(deleteFramebuffers, void, glDeleteFramebuffers, (GLsizei) n, (const GLuint *) framebuffers) { - postEvent<&deleteFramebuffers>(n, qMakePair(framebuffers, n)); + postEvent<&deleteFramebuffers>(qMakePair(framebuffers, n)); } QWEBGL_FUNCTION_POSTEVENT(deleteProgram, glDeleteProgram, @@ -632,7 +649,7 @@ QWEBGL_FUNCTION_POSTEVENT(deleteProgram, glDeleteProgram, QWEBGL_FUNCTION(deleteRenderbuffers, void, glDeleteRenderbuffers, (GLsizei) n, (const GLuint *) renderbuffers) { - postEvent<&deleteRenderbuffers>(n, qMakePair(renderbuffers, n)); + postEvent<&deleteRenderbuffers>(qMakePair(renderbuffers, n)); } QWEBGL_FUNCTION_POSTEVENT(deleteShader, glDeleteShader, @@ -641,7 +658,7 @@ QWEBGL_FUNCTION_POSTEVENT(deleteShader, glDeleteShader, QWEBGL_FUNCTION(deleteTextures, void, glDeleteTextures, (GLsizei) n, (const GLuint *) textures) { - postEvent<&deleteTextures>(n, qMakePair(textures, n)); + postEvent<&deleteTextures>(qMakePair(textures, n)); } QWEBGL_FUNCTION_POSTEVENT(depthFunc, glDepthFunc, @@ -666,7 +683,7 @@ QWEBGL_FUNCTION(disableVertexAttribArray, void, glDisableVertexAttribArray, QWEBGL_FUNCTION(drawArrays, void, glDrawArrays, (GLenum) mode, (GLint) first, (GLsizei) count) { - auto event = currentContext()->createEvent(QStringLiteral("drawArrays")); + auto event = currentContext()->createEvent(QStringLiteral("glDrawArrays")); if (!event) return; event->addParameters(mode, first, count); @@ -680,7 +697,7 @@ QWEBGL_FUNCTION(drawArrays, void, glDrawArrays, QWEBGL_FUNCTION(drawElements, void, glDrawElements, (GLenum) mode, (GLsizei) count, (GLenum) type, (const void *) indices) { - auto event = currentContext()->createEvent(QStringLiteral("drawElements")); + auto event = currentContext()->createEvent(QStringLiteral("glDrawElements")); if (!event) return; event->addParameters(mode, count, type); @@ -955,7 +972,7 @@ QWEBGL_FUNCTION(getFramebufferAttachmentParameteriv, void, glGetFramebufferAttac QWEBGL_FUNCTION(getProgramInfoLog, void, glGetProgramInfoLog, (GLuint) program, (GLsizei) bufSize, (GLsizei *) length, (GLchar *) infoLog) { - auto value = postEventAndQuery<&getProgramInfoLog>(QString(), program, bufSize); + auto value = postEventAndQuery<&getProgramInfoLog>(QString(), program); *length = value.length(); if (bufSize >= value.length()) std::memcpy(infoLog, value.constData(), value.length()); @@ -976,7 +993,7 @@ QWEBGL_FUNCTION(getRenderbufferParameteriv, void, glGetRenderbufferParameteriv, QWEBGL_FUNCTION(getShaderInfoLog, void, glGetShaderInfoLog, (GLuint) shader, (GLsizei) bufSize, (GLsizei *) length, (GLchar *) infoLog) { - const auto value = postEventAndQuery<&getShaderInfoLog>(QString(), shader, bufSize); + const auto value = postEventAndQuery<&getShaderInfoLog>(QString(), shader); *length = value.length(); if (bufSize >= value.length()) std::memcpy(infoLog, value.constData(), value.length()); @@ -1002,7 +1019,7 @@ QWEBGL_FUNCTION(getShaderPrecisionFormat, void, glGetShaderPrecisionFormat, QWEBGL_FUNCTION(getShaderSource, void, glGetShaderSource, (GLuint) shader, (GLsizei) bufSize, (GLsizei *) length, (GLchar *) source) { - const auto value = postEventAndQuery<&getShaderSource>(QString(), shader, bufSize); + const auto value = postEventAndQuery<&getShaderSource>(QString(), shader); *length = value.length(); if (bufSize >= value.length()) std::memcpy(source, value.constData(), value.length()); @@ -1176,17 +1193,15 @@ QWEBGL_FUNCTION(shaderSource, void, glShaderSource, (GLuint) shader, (GLsizei) count, (const GLchar *const *) string, (const GLint *) length) { - auto event = currentContext()->createEvent(QStringLiteral("shaderSource")); - if (!event) - return; - event->addParameters(shader, count); - for (int i = 0; i < count; ++i) { - if (!length) - event->addString(QString::fromLatin1(string[i])); - else - event->addString(QString::fromLatin1(string[i], length[i])); - } - QCoreApplication::postEvent(QWebGLIntegrationPrivate::instance()->webSocketServer, event); + QString fullString; + std::function<void(int)> concat; + if (length) + concat = [&](int i) { fullString.append(QString::fromLatin1(string[i], length[i])); }; + else + concat = [&](int i) { fullString.append(QString::fromLatin1(string[i])); }; + for (int i = 0; i < count; ++i) + concat(i); + postEvent<&shaderSource>(shader, fullString); } QWEBGL_FUNCTION_POSTEVENT(stencilFunc, glStencilFunc, @@ -1212,11 +1227,22 @@ QWEBGL_FUNCTION(texImage2D, void, glTexImage2D, (GLsizei) width, (GLsizei) height, (GLint) border, (GLenum) format, (GLenum) type, (const void *) pixels) { + const auto data = reinterpret_cast<const char *>(pixels); + const auto dataSize = imageSize(width, height, format, type, + currentContextData()->pixelStorage); + const bool isNull = data == nullptr || [](const char *pointer, int size) { + const char *const end = pointer + size; + const unsigned int zero = 0u; + const char *const late = end + 1 - sizeof(zero); + while (pointer < late) { // we have at least sizeof(zero) more bytes to check: + if (*reinterpret_cast<const unsigned int *>(pointer) != zero) + return false; + pointer += sizeof(zero); + } + return pointer >= end || std::memcmp(pointer, &zero, end - pointer) == 0; + }(data, dataSize); postEvent<&texImage2D>(target, level, internalformat, width, height, border, format, type, - pixels ? QByteArray((const char*)pixels, - imageSize(width, height, format, type, - currentContextData()->pixelStorage)) - : nullptr); + isNull ? nullptr : QByteArray(data, dataSize)); } QWEBGL_FUNCTION_POSTEVENT(texParameterf, glTexParameterf, @@ -1254,7 +1280,7 @@ QWEBGL_FUNCTION_POSTEVENT(uniform1f, glUniform1f, (GLint) location, (GLfloat) v0 QWEBGL_FUNCTION(uniform1fv, void, glUniform1fv, (GLint) location, (GLsizei) count, (const GLfloat *) value) { - postEvent<&uniform1fv>(location, count, qMakePair(value, count)); + postEvent<&uniform1fv>(location, qMakePair(value, count)); } QWEBGL_FUNCTION_POSTEVENT(uniform1i, glUniform1i, @@ -1263,7 +1289,7 @@ QWEBGL_FUNCTION_POSTEVENT(uniform1i, glUniform1i, QWEBGL_FUNCTION(uniform1iv, void, glUniform1iv, (GLint) location, (GLsizei) count, (const GLint *) value) { - postEvent<&uniform1iv>(location, count, qMakePair(value, count)); + postEvent<&uniform1iv>(location, qMakePair(value, count)); } QWEBGL_FUNCTION_POSTEVENT(uniform2f, glUniform2f, @@ -1272,7 +1298,7 @@ QWEBGL_FUNCTION_POSTEVENT(uniform2f, glUniform2f, QWEBGL_FUNCTION(uniform2fv, void, glUniform2fv, (GLint) location, (GLsizei) count, (const GLfloat *) value) { - postEvent<&uniform2fv>(location, count, qMakePair(value, count * 2)); + postEvent<&uniform2fv>(location, qMakePair(value, count * 2)); } QWEBGL_FUNCTION_POSTEVENT(uniform2i, glUniform2i, @@ -1281,17 +1307,16 @@ QWEBGL_FUNCTION_POSTEVENT(uniform2i, glUniform2i, QWEBGL_FUNCTION(uniform2iv, void, glUniform2iv, (GLint) location, (GLsizei) count, (const GLint *) value) { - postEvent<&uniform2iv>(location, count, qMakePair(value, count * 2)); + postEvent<&uniform2iv>(location, qMakePair(value, count * 2)); } QWEBGL_FUNCTION_POSTEVENT(uniform3f, glUniform3f, (GLint) location, (GLfloat) v0, (GLfloat) v1, (GLfloat) v2) - QWEBGL_FUNCTION(uniform3fv, void, glUniform3fv, (GLint) location, (GLsizei) count, (const GLfloat *) value) { - postEvent<&uniform3fv>(location, count, qMakePair(value, count * 3)); + postEvent<&uniform3fv>(location, qMakePair(value, count * 3)); } QWEBGL_FUNCTION_POSTEVENT(uniform3i, glUniform3i, @@ -1300,7 +1325,7 @@ QWEBGL_FUNCTION_POSTEVENT(uniform3i, glUniform3i, QWEBGL_FUNCTION(uniform3iv, void, glUniform3iv, (GLint) location, (GLsizei) count, (const GLint *) value) { - postEvent<&uniform3iv>(location, count, qMakePair(value, count * 3)); + postEvent<&uniform3iv>(location, qMakePair(value, count * 3)); } QWEBGL_FUNCTION_POSTEVENT(uniform4f, glUniform4f, @@ -1310,7 +1335,7 @@ QWEBGL_FUNCTION_POSTEVENT(uniform4f, glUniform4f, QWEBGL_FUNCTION(uniform4fv, void, glUniform4fv, (GLint) location, (GLsizei) count, (const GLfloat *) value) { - postEvent<&uniform4fv>(location, count, qMakePair(value, count * 4)); + postEvent<&uniform4fv>(location, qMakePair(value, count * 4)); } QWEBGL_FUNCTION_POSTEVENT(uniform4i, glUniform4i, @@ -1319,25 +1344,25 @@ QWEBGL_FUNCTION_POSTEVENT(uniform4i, glUniform4i, QWEBGL_FUNCTION(uniform4iv, void, glUniform4iv, (GLint) location, (GLsizei) count, (const GLint *) value) { - postEvent<&uniform4iv>(location, count, qMakePair(value, count * 4)); + postEvent<&uniform4iv>(location, qMakePair(value, count * 4)); } QWEBGL_FUNCTION(uniformMatrix2fv, void, glUniformMatrix2fv, (GLint) location, (GLsizei) count, (GLboolean) transpose, (const GLfloat *) value) { - postEvent<&uniformMatrix2fv>(location, count, transpose, qMakePair(value, count * 4)); + postEvent<&uniformMatrix2fv>(location, transpose, qMakePair(value, count * 4)); } QWEBGL_FUNCTION(uniformMatrix3fv, void, glUniformMatrix3fv, (GLint) location, (GLsizei) count, (GLboolean) transpose, (const GLfloat *) value) { - postEvent<&uniformMatrix3fv>(location, count, transpose, qMakePair(value, count * 9)); + postEvent<&uniformMatrix3fv>(location, transpose, qMakePair(value, count * 9)); } QWEBGL_FUNCTION(uniformMatrix4fv, void, glUniformMatrix4fv, (GLint) location, (GLsizei) count, (GLboolean) transpose, (const GLfloat *) value) { - postEvent<&uniformMatrix4fv>(location, count, transpose, qMakePair(value, count * 16)); + postEvent<&uniformMatrix4fv>(location, transpose, qMakePair(value, count * 16)); } QWEBGL_FUNCTION_POSTEVENT(useProgram, glUseProgram, @@ -1515,8 +1540,8 @@ bool QWebGLContext::isValid() const QFunctionPointer QWebGLContext::getProcAddress(const char *procName) { - const auto it = glFunctions.find(procName); - return it != glFunctions.end() ? (*it)->functionPointer : nullptr; + const auto it = GLFunction::byName.find(procName); + return it != GLFunction::byName.end() ? (*it)->functionPointer : nullptr; } int QWebGLContext::id() const @@ -1577,4 +1602,16 @@ QVariant QWebGLContext::queryValue(int id) return variant; } +QStringList QWebGLContext::supportedFunctions() +{ + return GLFunction::remoteFunctionNames; +} + +quint8 QWebGLContext::functionIndex(const QString &functionName) +{ + const auto it = GLFunction::byName.find(functionName); + Q_ASSERT(it != GLFunction::byName.end()); + return (*it)->id; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/webgl/qwebglcontext.h b/src/plugins/platforms/webgl/qwebglcontext.h index 7f7b7d7..4ba312d 100644 --- a/src/plugins/platforms/webgl/qwebglcontext.h +++ b/src/plugins/platforms/webgl/qwebglcontext.h @@ -60,6 +60,9 @@ public: static QWebGLFunctionCall *createEvent(const QString &functionName, bool wait = false); static QVariant queryValue(int id); + static QStringList supportedFunctions(); + static quint8 functionIndex(const QString &functionName); + private: Q_DISABLE_COPY(QWebGLContext) Q_DECLARE_PRIVATE(QWebGLContext) diff --git a/src/plugins/platforms/webgl/qwebglfunctioncall.cpp b/src/plugins/platforms/webgl/qwebglfunctioncall.cpp index 77134d8..26cdc7c 100644 --- a/src/plugins/platforms/webgl/qwebglfunctioncall.cpp +++ b/src/plugins/platforms/webgl/qwebglfunctioncall.cpp @@ -136,6 +136,12 @@ void QWebGLFunctionCall::addData(const QByteArray &data) d->parameters.append(data); } +void QWebGLFunctionCall::addList(const QVariantList &list) +{ + Q_D(QWebGLFunctionCall); + d->parameters.append(QVariant::fromValue(list)); +} + void QWebGLFunctionCall::addNull() { Q_D(QWebGLFunctionCall); diff --git a/src/plugins/platforms/webgl/qwebglfunctioncall.h b/src/plugins/platforms/webgl/qwebglfunctioncall.h index 8d24d80..ed540b1 100644 --- a/src/plugins/platforms/webgl/qwebglfunctioncall.h +++ b/src/plugins/platforms/webgl/qwebglfunctioncall.h @@ -64,6 +64,7 @@ public: void addUInt(uint value); void addFloat(float value); void addData(const QByteArray &data); + void addList(const QVariantList &list); void addNull(); void add(const QString &value) { addString(value); } @@ -72,6 +73,7 @@ public: void add(uint value) { addUInt(value); } void add(float value) { addFloat(value); } void add(const QByteArray &data) { addData(data); } + void add(const QVariantList &list) { addList(list); } void add(std::nullptr_t) { addNull(); } template<class...Ts> diff --git a/src/plugins/platforms/webgl/qwebglintegration.cpp b/src/plugins/platforms/webgl/qwebglintegration.cpp index 121debf..8c17190 100644 --- a/src/plugins/platforms/webgl/qwebglintegration.cpp +++ b/src/plugins/platforms/webgl/qwebglintegration.cpp @@ -179,6 +179,7 @@ QPlatformTheme *QWebGLIntegration::createPlatformTheme(const QString &name) cons QPlatformBackingStore *QWebGLIntegration::createPlatformBackingStore(QWindow *window) const { Q_UNUSED(window); + qCCritical(lcWebGL, "WebGL QPA platform plugin: Raster surfaces are not supported"); return nullptr; } @@ -257,14 +258,13 @@ QPlatformOpenGLContext *QWebGLIntegration::createPlatformOpenGLContext(QOpenGLCo bool QWebGLIntegration::hasCapability(QPlatformIntegration::Capability cap) const { - // We assume that devices will have more and not less capabilities switch (cap) { - case ThreadedPixmaps: return true; - case OpenGL: return true; - case ThreadedOpenGL: return true; - case WindowManagement: return false; - case RasterGLSurface: return true; - default: return QPlatformIntegration::hasCapability(cap); + case OpenGL: + case ThreadedOpenGL: + case ThreadedPixmaps: + return true; + default: + return false; } } diff --git a/src/plugins/platforms/webgl/qwebglintegration_p.h b/src/plugins/platforms/webgl/qwebglintegration_p.h index 2bd4d9d..06f19fc 100644 --- a/src/plugins/platforms/webgl/qwebglintegration_p.h +++ b/src/plugins/platforms/webgl/qwebglintegration_p.h @@ -43,6 +43,7 @@ #include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h> #include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h> #elif defined(Q_OS_MACOS) +#include <QtFontDatabaseSupport/private/qfontengine_coretext_p.h> #include <QtFontDatabaseSupport/private/qcoretextfontdatabase_p.h> #include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h> #else @@ -73,7 +74,7 @@ public: #if defined(Q_OS_WIN) mutable QWindowsFontDatabase fontDatabase; #elif defined(Q_OS_MACOS) - mutable QCoreTextFontDatabase fontDatabase; + mutable QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine> fontDatabase; #else mutable QGenericUnixFontDatabase fontDatabase; #endif diff --git a/src/plugins/platforms/webgl/qwebglwebsocketserver.cpp b/src/plugins/platforms/webgl/qwebglwebsocketserver.cpp index f41d2fe..ab90950 100644 --- a/src/plugins/platforms/webgl/qwebglwebsocketserver.cpp +++ b/src/plugins/platforms/webgl/qwebglwebsocketserver.cpp @@ -175,45 +175,54 @@ void QWebGLWebSocketServer::sendMessage(QWebSocket *socket, QByteArray data; { QDataStream stream(&data, QIODevice::WriteOnly); - stream << functionName; + stream << QWebGLContext::functionIndex(functionName); if (values.contains("id")) { auto ok = false; stream << quint32(values["id"].toUInt(&ok)); Q_ASSERT(ok); } - stream << parameterCount; - for (const auto &value : qAsConst(parameters)) { - if (value.isNull()) { - stream << (quint8)'n'; - } else switch (value.type()) { - case QVariant::Int: - stream << (quint8)'i' << value.toInt(); - break; - case QVariant::UInt: - stream << (quint8)'u' << value.toUInt(); - break; - case QVariant::Bool: - stream << (quint8)'b' << (quint8)value.toBool(); - break; - case QVariant::Double: - stream << (quint8)'d' << value.toDouble(); - break; - case QVariant::String: - stream << (quint8)'s' << value.toString().toUtf8(); - break; - case QVariant::ByteArray: { - const auto byteArray = value.toByteArray(); - if (byteArray.isNull()) + const std::function<void(const QVariantList &)> serialize = [&stream, &serialize]( + const QVariantList ¶meters) { + for (const auto &value : parameters) { + if (value.isNull()) { stream << (quint8)'n'; - else - stream << (quint8)'x' << byteArray; - break; + } else switch (value.type()) { + case QVariant::Int: + stream << (quint8)'i' << value.toInt(); + break; + case QVariant::UInt: + stream << (quint8)'u' << value.toUInt(); + break; + case QVariant::Bool: + stream << (quint8)'b' << (quint8)value.toBool(); + break; + case QVariant::Double: + stream << (quint8)'d' << value.toDouble(); + break; + case QVariant::String: + stream << (quint8)'s' << value.toString().toUtf8(); + break; + case QVariant::ByteArray: { + const auto byteArray = value.toByteArray(); + if (byteArray.isNull()) + stream << (quint8)'n'; + else + stream << (quint8)'x' << byteArray; + break; + } + case QVariant::List: { + const auto list = value.toList(); + stream << quint8('a') << quint8(list.size()); + serialize(list); + break; + } + default: + qCCritical(lc, "Unsupported type: %d", value.type()); + break; + } } - default: - qCCritical(lc, "Unsupported type: %d", value.type()); - break; - } - } + }; + serialize(parameters); stream << (quint32)0xbaadf00d; } const quint32 totalMessageSize = data.size(); @@ -295,6 +304,8 @@ void QWebGLWebSocketServer::onNewConnection() #endif }, { QStringLiteral("loadingScreen"), qgetenv("QT_WEBGL_LOADINGSCREEN") }, + { QStringLiteral("supportedFunctions"), + QVariant::fromValue(QWebGLContext::supportedFunctions()) }, { "sysinfo", QVariantMap { { QStringLiteral("buildAbi"), QSysInfo::buildAbi() }, diff --git a/src/plugins/platforms/webgl/qwebglwindow.cpp b/src/plugins/platforms/webgl/qwebglwindow.cpp index 46c6c1b..9bc0b7c 100644 --- a/src/plugins/platforms/webgl/qwebglwindow.cpp +++ b/src/plugins/platforms/webgl/qwebglwindow.cpp @@ -149,6 +149,12 @@ QWebGLScreen *QWebGLWindow::screen() const return static_cast<QWebGLScreen *>(QPlatformWindow::screen()); } +void QWebGLWindow::setGeometry(const QRect &rect) +{ + QWindowSystemInterface::handleGeometryChange(window(), rect); + QPlatformWindow::setGeometry(rect); +} + void QWebGLWindow::setDefaults(const QMap<GLenum, QVariant> &values) { Q_D(QWebGLWindow); diff --git a/src/plugins/platforms/webgl/qwebglwindow.h b/src/plugins/platforms/webgl/qwebglwindow.h index 972207c..4d0a8c2 100644 --- a/src/plugins/platforms/webgl/qwebglwindow.h +++ b/src/plugins/platforms/webgl/qwebglwindow.h @@ -63,6 +63,7 @@ public: QWebGLScreen *screen() const; + void setGeometry(const QRect &rect) override; void setDefaults(const QMap<GLenum, QVariant> &values); private: diff --git a/src/plugins/platforms/webgl/webqt.jsx b/src/plugins/platforms/webgl/webqt.jsx index 3d775ec..53158b1 100644 --- a/src/plugins/platforms/webgl/webqt.jsx +++ b/src/plugins/platforms/webgl/webqt.jsx @@ -65,6 +65,7 @@ window.onload = function () { } }; } + var supportedFunctions; var sendObject = function (obj) { socket.send(JSON.stringify(obj)); } @@ -455,8 +456,8 @@ window.onload = function () { gl.deleteFramebuffers = function(n) { var d = contextData[currentContext]; - for (var i = 0; i < n; ++i) - gl.deleteFramebuffer(d.framebufferMap[arguments[1 + i]]); + for (var i in framebuffers) + gl.deleteFramebuffer(d.framebufferMap[framebuffers[i]]); }; gl._deleteProgram = gl.deleteProgram; @@ -467,8 +468,8 @@ window.onload = function () { gl.deleteRenderbuffers = function() { var d = contextData[currentContext]; - for (var i in arguments) - gl.deleteRenderbuffer(d.renderbufferMap[arguments[i]]); + for (var i in renderbuffers) + gl.deleteRenderbuffer(d.renderbufferMap[renderbuffers[i]]); }; gl._deleteShader = gl.deleteShader; @@ -477,9 +478,9 @@ window.onload = function () { gl._deleteShader(d.shaderMap[remoteShader].shader); }; - gl.deleteTextures = function(n) { - for (var i = 0; i < n; ++i) - gl.deleteTexture(mapTexture(currentContext, arguments[1 + i])); + gl.deleteTextures = function(textures) { + for (var i in textures) + gl.deleteTexture(mapTexture(currentContext, textures[i])); }; gl._drawElements = gl.drawElements; @@ -708,11 +709,9 @@ window.onload = function () { }; gl._shaderSource = gl.shaderSource; - gl.shaderSource = function(shader, count) { + gl.shaderSource = function(shader, source) { var d = contextData[currentContext]; - d.shaderMap[shader].source = ""; - for (var i = 0; i < count; ++i) - d.shaderMap[shader].source += arguments[2 + i] + "\n"; + d.shaderMap[shader].source = source; gl._shaderSource(d.shaderMap[shader].shader, d.shaderMap[shader].source); }; @@ -723,30 +722,21 @@ window.onload = function () { }; gl._uniform1fv = gl.uniform1fv; - gl.uniform1fv = function(location, count) { + gl.uniform1fv = function(location, value) { var d = contextData[currentContext]; - var data = []; - for (var i = 0; i < count; ++i) - data.push(arguments[i + 2]); - gl._uniform1fv(d.uniformLocationMap[location], data); + gl._uniform1fv(d.uniformLocationMap[location], value); }; gl._uniform2fv = gl.uniform2fv; - gl.uniform2fv = function(location, count) { + gl.uniform2fv = function(location, value) { var d = contextData[currentContext]; - var data = []; - for (var i = 0; i < count * 2; ++i) - data.push(arguments[i + 2]); - gl._uniform2fv(d.uniformLocationMap[location], data); + gl._uniform2fv(d.uniformLocationMap[location], value); }; gl._uniform3fv = gl.uniform3fv; - gl.uniform3fv = function(location, count) { + gl.uniform3fv = function(location, value) { var d = contextData[context]; - var data = []; - for (var i = 0; i < count * 3; ++i) - data.push(arguments[i + 2]); - gl._uniform3fv(d.uniformLocationMap[location], data); + gl._uniform3fv(d.uniformLocationMap[location], value); }; gl._uniform1i = gl.uniform1i; @@ -756,29 +746,20 @@ window.onload = function () { }; gl._uniform4fv = gl.uniform4fv; - gl.uniform4fv = function(location, count) { + gl.uniform4fv = function(location, value) { var d = contextData[currentContext]; - var data = []; - for (var i = 0; i < count * 4; ++i) - data.push(arguments[i + 2]); - gl._uniform4fv(d.uniformLocationMap[location], data); + gl._uniform4fv(d.uniformLocationMap[location], value); }; gl._uniformMatrix3fv = gl.uniformMatrix3fv; - gl.uniformMatrix3fv = function(location, count, transpose) { + gl.uniformMatrix3fv = function(location, transpose, data) { var d = contextData[currentContext]; - var data = []; - for (var i = 0; i < count * 9; ++i) - data.push(arguments[i + 3]); gl._uniformMatrix3fv(d.uniformLocationMap[location], transpose, data); }; gl._uniformMatrix4fv = gl.uniformMatrix4fv; - gl.uniformMatrix4fv = function(location, count, transpose) { + gl.uniformMatrix4fv = function(location, transpose, data) { var d = contextData[currentContext]; - var data = []; - for (var i = 0; i < count * 16; ++i) - data.push(arguments[i + 3]); gl._uniformMatrix4fv(d.uniformLocationMap[location], transpose, data); }; @@ -849,39 +830,39 @@ window.onload = function () { } - var commandsNeedingResponse = [ - "swapBuffers", - "checkFramebufferStatus", - "createProgram", - "createShader", - "genBuffers", - "genFramebuffers", - "genRenderbuffers", - "genTextures", - "getAttachedShaders", - "getAttribLocation", - "getBooleanv", - "getError", - "getFramebufferAttachmentParameteriv", - "getIntegerv", - "getParameter", - "getProgramInfoLog", - "getProgramiv", - "getRenderbufferParameteriv", - "getShaderiv", - "getShaderPrecisionFormat", - "getString", - "getTexParameterfv", - "getTexParameteriv", - "getUniformfv", - "getUniformLocation", - "getUniformiv", - "getVertexAttribfv", - "getVertexAttribiv", - "getShaderSource", - "getShaderInfoLog", - "isRenderbuffer" - ]; + var commandsNeedingResponse = { + "swapBuffers" : undefined, + "checkFramebufferStatus" : undefined, + "createProgram" : undefined, + "createShader" : undefined, + "genBuffers" : undefined, + "genFramebuffers" : undefined, + "genRenderbuffers" : undefined, + "genTextures" : undefined, + "getAttachedShaders" : undefined, + "getAttribLocation" : undefined, + "getBooleanv" : undefined, + "getError" : undefined, + "getFramebufferAttachmentParameteriv" : undefined, + "getIntegerv" : undefined, + "getParameter" : undefined, + "getProgramInfoLog" : undefined, + "getProgramiv" : undefined, + "getRenderbufferParameteriv" : undefined, + "getShaderiv" : undefined, + "getShaderPrecisionFormat" : undefined, + "getString" : undefined, + "getTexParameterfv" : undefined, + "getTexParameteriv" : undefined, + "getUniformfv" : undefined, + "getUniformLocation" : undefined, + "getUniformiv" : undefined, + "getVertexAttribfv" : undefined, + "getVertexAttribiv" : undefined, + "getShaderSource" : undefined, + "getShaderInfoLog" : undefined, + "isRenderbuffer" : undefined + }; var ensureContextData = function (context) { if (!(context in contextData)) { @@ -967,57 +948,67 @@ window.onload = function () { var offset = 0; var obj = { "parameters" : [] }; - obj["functionNameSize"] = view.getUint32(offset); - offset += 4; - obj["function"] = textDecoder.decode(new Uint8Array(buffer, offset, obj.functionNameSize)); - offset += obj.functionNameSize; - for (var i in commandsNeedingResponse) { - if (commandsNeedingResponse[i] === obj.function) { - obj["id"] = view.getUint32(offset); - offset += 4; - break; - } + obj["function"] = supportedFunctions[view.getUint8(offset)]; + offset += 1; + if (obj.function in commandsNeedingResponse) { + obj["id"] = view.getUint32(offset); + offset += 4; } - obj["parameterCount"] = view.getUint32(offset); - offset += 4; - for (var i = 0; i < obj.parameterCount; ++i) { - var character = view.getUint8(offset); - offset += 1; - var parameterType = String.fromCharCode(character); - if (parameterType === 'i') { - obj.parameters.push(view.getInt32(offset)); - offset += 4; - } else if (parameterType === 'u') { - obj.parameters.push(view.getUint32(offset)); - offset += 4; - } else if (parameterType === 'd') { - obj.parameters.push(view.getFloat64(offset)); - offset += 8; - } else if (parameterType === 'b') { - obj.parameters.push(view.getUint8(offset) === 1); + if (obj["function"] === "makeCurrent") + obj["parameterCount"] = 4; + else if (obj["function"] === "swapBuffers") + obj["parameterCount"] = 0; + else if (obj["function"] == "drawArrays") + obj["parameterCount"] = null; // glDrawArrays has a variable number of arguments + else + obj["parameterCount"] = gl[obj["function"]].length; + function deserialize(container, count) { + for (var i = 0; count != null ? i < count : offset + 4 < buffer.byteLength; ++i) { + var character = view.getUint8(offset); offset += 1; - break; - } else if (parameterType === 's') { - var stringSize = view.getUint32(offset); - offset += 4; - var string = textDecoder.decode(new Uint8Array(buffer, offset, stringSize)); - obj.parameters.push(string); - offset += stringSize; - } else if (parameterType === 'x') { - var dataSize = view.getUint32(offset); - offset += 4; - var data = new Uint8Array(buffer, offset, dataSize); - var bytesRead = data.byteLength; - if (bytesRead !== dataSize) - console.error("invalid data"); - obj.parameters.push(data); - offset += dataSize; - } else if (parameterType === 'n') { - obj.parameters.push(null); + var parameterType = String.fromCharCode(character); + if (parameterType === 'i') { + container.push(view.getInt32(offset)); + offset += 4; + } else if (parameterType === 'u') { + container.push(view.getUint32(offset)); + offset += 4; + } else if (parameterType === 'd') { + container.push(view.getFloat64(offset)); + offset += 8; + } else if (parameterType === 'b') { + container.push(view.getUint8(offset) === 1); + offset += 1; + break; + } else if (parameterType === 's') { + var stringSize = view.getUint32(offset); + offset += 4; + var string = textDecoder.decode(new Uint8Array(buffer, offset, stringSize)); + container.push(string); + offset += stringSize; + } else if (parameterType === 'x') { + var dataSize = view.getUint32(offset); + offset += 4; + var data = new Uint8Array(buffer, offset, dataSize); + var bytesRead = data.byteLength; + if (bytesRead !== dataSize) + console.error("invalid data"); + container.push(data); + offset += dataSize; + } else if (parameterType === 'n') { + container.push(null); + } else if (parameterType === 'a') { + var dataSize = view.getUint8(offset); + offset += 1; + deserialize(container[container.push([]) - 1], dataSize); + } else { + console.error("Unsupported type :" + character); + } } - } + }; + deserialize(obj.parameters, obj.parameterCount); var magic = view.getUint32(offset); - if (magic !== 0xbaadf00d) + if (magic !== 0xbaadf00d) // sentinel expected at end of buffer console.error('Invalid magic'); offset += 4; if (offset !== buffer.byteLength) @@ -1085,11 +1076,8 @@ window.onload = function () { var d = contextData[currentContext]; if (d) d.glCommands.push(obj); - for (var i in commandsNeedingResponse) - if (commandsNeedingResponse[i] === obj.function) { - execGL(currentContext); - break; - } + if (obj.function in commandsNeedingResponse) + execGL(currentContext); }; socket.onopen = function (event) { @@ -1159,6 +1147,7 @@ window.onload = function () { } else if (obj.type === "change_title") { document.title = obj.text; } else if (obj.type === "connect") { + supportedFunctions = obj["supportedFunctions"]; var sysinfo = obj["sysinfo"]; if (obj["debug"]) DEBUG = 1; |