summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-01-09 21:52:56 +0100
committerLiang Qi <liang.qi@qt.io>2018-01-09 21:53:21 +0100
commit6035467b37bc71b0ea25155fa70f85bee054d1a3 (patch)
treec2787b12c73706f18e03c148eea6241dc43fdb97
parent09bac2983badd9698bdfe499fd93d53364579876 (diff)
parentbc8fefc2470ccb2ecc2edaab9822f71be09fa901 (diff)
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts: .qmake.conf Change-Id: Ib0005461e6abb8dfeb4f9697df54421b00b67f03
-rw-r--r--qtwebglplugin.pro2
-rw-r--r--src/plugins/platforms/webgl/qwebglcontext.cpp157
-rw-r--r--src/plugins/platforms/webgl/qwebglcontext.h3
-rw-r--r--src/plugins/platforms/webgl/qwebglfunctioncall.cpp6
-rw-r--r--src/plugins/platforms/webgl/qwebglfunctioncall.h2
-rw-r--r--src/plugins/platforms/webgl/qwebglintegration.cpp14
-rw-r--r--src/plugins/platforms/webgl/qwebglintegration_p.h3
-rw-r--r--src/plugins/platforms/webgl/qwebglwebsocketserver.cpp75
-rw-r--r--src/plugins/platforms/webgl/qwebglwindow.cpp6
-rw-r--r--src/plugins/platforms/webgl/qwebglwindow.h1
-rw-r--r--src/plugins/platforms/webgl/webqt.jsx237
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 &parameters) {
+ 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;