diff options
author | Jesus Fernandez <jesus.fernandez@qt.io> | 2017-09-20 15:36:02 +0200 |
---|---|---|
committer | Jesus Fernandez <Jesus.Fernandez@qt.io> | 2017-12-05 13:55:28 +0000 |
commit | f73929c2c6c9229f71470502faab14178d561157 (patch) | |
tree | 1d44d555d80dc48425d2f7c7db13425df88c8f76 | |
parent | 8d3d896cc2d47f2d4e1bffee60a159e8a60b6b43 (diff) |
Remove the parameterCount parameter
Saves 4 bytes per message. Combined with other optimizations, this
can save a lot of bandwidth.
It also adds a new serialization type, the array. The parameter count
cannot be removed without supporting arrays.
Change-Id: I5f9c0901d50fb7d9613461d9860338e18dcbe3cd
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
-rw-r--r-- | src/plugins/platforms/webgl/qwebglcontext.cpp | 72 | ||||
-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/qwebglwebsocketserver.cpp | 71 | ||||
-rw-r--r-- | src/plugins/platforms/webgl/webqt.jsx | 145 |
5 files changed, 156 insertions, 140 deletions
diff --git a/src/plugins/platforms/webgl/qwebglcontext.cpp b/src/plugins/platforms/webgl/qwebglcontext.cpp index b77aa7f..be62649 100644 --- a/src/plugins/platforms/webgl/qwebglcontext.cpp +++ b/src/plugins/platforms/webgl/qwebglcontext.cpp @@ -250,13 +250,22 @@ template<class POINTER, class COUNT> inline QWebGLFunctionCall *addHelper(QWebGLFunctionCall *event, const QPair<POINTER, COUNT> &elements) { - if (event) { - for (auto i = 0; i < elements.second; ++i) - event->add(elements.first[i]); - } + 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 *event, const T &value) { @@ -631,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, @@ -640,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, @@ -649,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, @@ -963,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()); @@ -984,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()); @@ -1010,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()); @@ -1184,17 +1193,15 @@ QWEBGL_FUNCTION(shaderSource, void, glShaderSource, (GLuint) shader, (GLsizei) count, (const GLchar *const *) string, (const GLint *) length) { - auto event = currentContext()->createEvent(QStringLiteral("glShaderSource")); - 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, @@ -1273,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, @@ -1282,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, @@ -1291,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, @@ -1300,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, @@ -1319,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, @@ -1329,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, @@ -1338,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, 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/qwebglwebsocketserver.cpp b/src/plugins/platforms/webgl/qwebglwebsocketserver.cpp index b9b3201..ab90950 100644 --- a/src/plugins/platforms/webgl/qwebglwebsocketserver.cpp +++ b/src/plugins/platforms/webgl/qwebglwebsocketserver.cpp @@ -181,39 +181,48 @@ void QWebGLWebSocketServer::sendMessage(QWebSocket *socket, 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(); diff --git a/src/plugins/platforms/webgl/webqt.jsx b/src/plugins/platforms/webgl/webqt.jsx index 0c58a6b..4d68c63 100644 --- a/src/plugins/platforms/webgl/webqt.jsx +++ b/src/plugins/platforms/webgl/webqt.jsx @@ -456,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; @@ -468,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; @@ -478,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; @@ -709,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); }; @@ -724,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) { - var d = contextData[currentContext]; - var data = []; - for (var i = 0; i < count * 3; ++i) - data.push(arguments[i + 2]); - gl._uniform3fv(d.uniformLocationMap[location], data); + gl.uniform3fv = function(location, value) { + var d = contextData[context]; + gl._uniform3fv(d.uniformLocationMap[location], value); }; gl._uniform1i = gl.uniform1i; @@ -757,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); }; @@ -974,44 +954,57 @@ window.onload = function () { 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 + obj["parameterCount"] = gl[obj["function"]].length; + function deserialize(container, count) { + for (var i = 0; i < count; ++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) console.error('Invalid magic'); |