summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSvenn-Arne Dragly <s@dragly.com>2016-02-25 15:36:22 +0100
committerMorten Johan Sørvig <morten.sorvig@qt.io>2016-05-02 21:35:56 +0000
commitf4f5219f0017d36e1b14fc4b88e9006b59c75b3f (patch)
tree2857566989115502c2be5846b6adfffb76825ee7
parent375adf412f44466a9ef588529ebbf7f102878919 (diff)
Update support for Emscripten
Change-Id: I5d696f0dbc188acb4faad83240f7b1aa7177dc48 Reviewed-by: Svenn-Arne Dragly <s@dragly.com> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
-rw-r--r--mkspecs/features/qt.prf25
-rw-r--r--mkspecs/unsupported/nacl-emscripten/qmake.conf22
-rwxr-xr-xnacl-configure5
-rw-r--r--src/corelib/global/qsystemdetection.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp5
-rw-r--r--src/corelib/kernel/qfunctions_nacl.cpp13
-rw-r--r--src/corelib/kernel/qfunctions_nacl.h4
-rw-r--r--src/corelib/plugin/qlibrary.cpp2
-rw-r--r--src/corelib/plugin/qplugin.h16
-rw-r--r--src/corelib/thread/qmutex.cpp6
-rw-r--r--src/corelib/thread/qmutex_unix.cpp4
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp17
-rw-r--r--src/corelib/tools/qsimd.cpp4
-rw-r--r--src/gui/opengl/qopenglfunctions.h2
-rw-r--r--src/gui/opengl/qopengltexturehelper.cpp56
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/audio.js5
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/base.js64
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/common.js415
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/file.js5
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/gles.js79
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/gles_ext.js28
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_2d.js5
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_3d.js10
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/input_events.js39
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/mouse_lock.js5
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/ppapi_preamble.js21
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/testing.js5
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/url_loader.js5
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/view.js16
-rw-r--r--src/plugins/platforms/pepper/3rdparty/pepper.js/web_socket.js5
-rw-r--r--src/plugins/platforms/pepper/pepper.js.pri52
-rw-r--r--src/plugins/platforms/pepper/qpeppereventdispatcher.cpp35
-rw-r--r--src/plugins/platforms/pepper/qpeppereventdispatcher.h1
-rw-r--r--src/plugins/platforms/pepper/qpepperfontdatabase.cpp2
-rw-r--r--src/plugins/platforms/pepper/qpepperglcontext.cpp14
-rw-r--r--src/plugins/platforms/pepper/qpepperpluginmain.cpp75
-rw-r--r--src/tools/nacldeployqt/main.cpp16
-rw-r--r--src/tools/nacldeployqt/template_qtloader.cpp25
38 files changed, 1000 insertions, 110 deletions
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index f62b6bb139..06d1afe5ea 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -278,6 +278,31 @@ contains(qt_module_deps, qml): \
"rsync -r --exclude='*.a' --exclude='*.prl' --exclude='*.qmltypes' "
macx-xcode: QMAKE_POST_LINK += "$p/ $$qmlTargetPath; done"
else: QMAKE_POST_LINK += "\$\$p/ $$qmlTargetPath; done"
+ } else:emscripten {
+ isEmpty(QMAKE_QML_BUNDLE_PATH):QMAKE_QML_BUNDLE_PATH = "qt_qml"
+ qmlTargetPath = $$OUT_PWD/$$QMAKE_QML_BUNDLE_PATH
+ qtconfTargetPath = $$OUT_PWD/qt.conf
+
+ # set import path in qt.conf to point to the bundeled qml:
+ QT_CONF_CONTENTS = \
+ "[Paths]" \
+ "Imports = $$QMAKE_QML_BUNDLE_PATH" \
+ "Qml2Imports = $$QMAKE_QML_BUNDLE_PATH"
+ write_file("$$OUT_PWD/qt.conf", QT_CONF_CONTENTS)|error("Aborting.")
+
+ # write qt.conf and copy each qml import dir into the bundle.
+ # But strip away archives and other files that are not needed:
+ !isEmpty(QMAKE_POST_LINK): QMAKE_POST_LINK += ";"
+ QMAKE_POST_LINK += \
+ "test -d $$qmlTargetPath && rm -r $$qmlTargetPath; " \
+ "mkdir -p $$qmlTargetPath && " \
+ "for p in $$QMLPATHS; do" \
+ "rsync -r --exclude='*.a' --exclude='*.so' --exclude='*.prl' --exclude='*.qmltypes' " \
+ "\$\$p/ $$qmlTargetPath; done"
+
+ # Add the folder and qt.conf to be preloaded by emscripten
+ QMAKE_LFLAGS += --preload-file qt_qml
+ QMAKE_LFLAGS += --preload-file qt.conf
}
}
}
diff --git a/mkspecs/unsupported/nacl-emscripten/qmake.conf b/mkspecs/unsupported/nacl-emscripten/qmake.conf
index 8b28a753a4..819ab58b72 100644
--- a/mkspecs/unsupported/nacl-emscripten/qmake.conf
+++ b/mkspecs/unsupported/nacl-emscripten/qmake.conf
@@ -2,6 +2,8 @@
# qmake configuration for building with nacl-emscripten
#
+QMAKE_INCDIR += $$(EMSCRIPTEN)/system/include
+
include(../../common/unix.conf)
include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)
@@ -16,22 +18,30 @@ QMAKE_LINK = em++
QMAKE_LINK_SHLIB = em++
QMAKE_AR = emar r
-CONFIG += emscripten
+CONFIG *= emscripten
# Uset default NaCl setting
QMAKE_LIBS_OPENGL_ES2=
-# Qt adds -I/path/to/qt/include, which triggers a "may be host include"
-# warning. It isn't: silence the warning.
-QMAKE_CXXFLAGS += -Wno-warn-absolute-paths
-QMAKE_LFLAGS += -Wl,-Wno-warn-absolute-paths
+emscripten_pthreads {
+ CONFIG += emscripten_pthreads
+ QMAKE_CXXFLAGS += -s USE_PTHREADS=1 \
+
+ QMAKE_LFLAGS += -s USE_PTHREADS=1 \
+ -s PTHREAD_POOL_SIZE=4\
+
+}
+
+QMAKE_LFLAGS += -Wl
# Add link-time pepper platform plugin javascript dependencies and
# required emscripten linker options.
PEPPER_JS_PATH=$$PWD/../../../src/plugins/platforms/pepper/3rdparty/pepper.js
+
QMAKE_LFLAGS += \
-s RESERVED_FUNCTION_POINTERS=400\
- -s TOTAL_MEMORY=512000000\
+ -s TOTAL_MEMORY=1280000000\
+ -s FULL_ES2=1 \
-s EXPORTED_FUNCTIONS=\"[\'_DoPostMessage\', \'_DoChangeView\', \'_DoChangeFocus\', \'_NativeCreateInstance\', \'_HandleInputEvent\']\"\
--pre-js $${PEPPER_JS_PATH}/ppapi_preamble.js\
--pre-js $${PEPPER_JS_PATH}/base.js\
diff --git a/nacl-configure b/nacl-configure
index 3dbd9fda9c..d53bc6bec0 100755
--- a/nacl-configure
+++ b/nacl-configure
@@ -229,6 +229,10 @@ fi
if [[ $TOOLCHAIN == emscripten ]]
then
NACL_CONFIGURE_LINE="$NACL_CONFIGURE_LINE -no-xlib -no-xcb-xlib -no-eglfs"
+ # emscripten needs to enforce OpenGL ES 2
+ NACL_CONFIGURE_LINE="$NACL_CONFIGURE_LINE -opengl es2"
+ # emscripten needs a static build for plugins to work properly
+ NACL_CONFIGURE_LINE="$NACL_CONFIGURE_LINE -static"
fi
# set release/debug build
@@ -247,4 +251,3 @@ echo $NACL_CONFIGURE_LINE
# Run configure
$NACL_CONFIGURE_LINE
-
diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h
index 250f186926..74c734e245 100644
--- a/src/corelib/global/qsystemdetection.h
+++ b/src/corelib/global/qsystemdetection.h
@@ -330,7 +330,9 @@
# define Q_OS_PNACL
#endif
#ifdef __EMSCRIPTEN__
+# ifndef Q_OS_NACL_EMSCRIPTEN
# define Q_OS_NACL_EMSCRIPTEN
+# endif
#endif
#endif
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp
index 58164dba47..60b46a35f5 100644
--- a/src/corelib/kernel/qeventdispatcher_unix.cpp
+++ b/src/corelib/kernel/qeventdispatcher_unix.cpp
@@ -190,12 +190,15 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags,
int wakeUpFd = initThreadWakeUp();
highest = qMax(highest, wakeUpFd);
#endif
-
+#ifdef Q_OS_NACL_EMSCRIPTEN
+ nsel = 0;
+#else
nsel = q->select(highest + 1,
&sn_vec[0].select_fds,
&sn_vec[1].select_fds,
&sn_vec[2].select_fds,
timeout);
+#endif
} while (nsel == -1 && (errno == EINTR || errno == EAGAIN));
if (nsel == -1) {
diff --git a/src/corelib/kernel/qfunctions_nacl.cpp b/src/corelib/kernel/qfunctions_nacl.cpp
index 5234452581..1c66ea5b23 100644
--- a/src/corelib/kernel/qfunctions_nacl.cpp
+++ b/src/corelib/kernel/qfunctions_nacl.cpp
@@ -82,7 +82,6 @@ void pthread_testcancel(void)
}
-
int pthread_cancel(pthread_t)
{
return 0;
@@ -140,10 +139,12 @@ int sigaction(int, const struct sigaction *, struct sigaction *)
return 0;
}
+#ifndef Q_OS_NACL_EMSCRIPTEN
int open(const char *, int, ...)
{
return 0;
}
+#endif
int open64(const char *, int, ...)
{
@@ -155,12 +156,12 @@ long pathconf(const char *, int)
return 0;
}
+#ifndef Q_OS_NACL_EMSCRIPTEN
int access(const char *, int)
{
return 0;
}
-#ifndef Q_OS_NACL_EMSCRIPTEN
typedef long off64_t;
off64_t ftello64(void *)
{
@@ -197,8 +198,6 @@ int unsetenv(const char *name)
}
#endif
-} // Extern C
-
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *)
{
return 0;
@@ -209,10 +208,9 @@ int pselect(int nfds, fd_set * readfds, fd_set * writefds, fd_set * errorfds, co
return 0;
}
-#ifdef Q_OS_NACL_EMSCRIPTEN
-
-// pthread stubs (no thrading support in emscripten)
+} // Extern C
+#if defined(Q_OS_NACL_EMSCRIPTEN) && !defined(__EMSCRIPTEN_PTHREADS__)
int pthread_setcancelstate(int state, int *oldstate)
{
return 0;
@@ -332,7 +330,6 @@ int sched_get_priority_min(int policy)
{
return 0;
}
-
#endif
// Several Qt components (such at the QtCore event dispatcher and networking)
diff --git a/src/corelib/kernel/qfunctions_nacl.h b/src/corelib/kernel/qfunctions_nacl.h
index 34e0efda1d..915f9c4220 100644
--- a/src/corelib/kernel/qfunctions_nacl.h
+++ b/src/corelib/kernel/qfunctions_nacl.h
@@ -128,11 +128,11 @@ int setenv(const char *name, const char *value, int overwrite) __attribute__((we
int unsetenv(const char *name) __attribute__((weak));
#endif
-}
-
int select(int nfds, fd_set * readfds, fd_set * writefds, fd_set * errorfds, struct timeval * timeout) __attribute__((weak));
int pselect(int nfds, fd_set * readfds, fd_set * writefds, fd_set * errorfds, const struct timespec * timeout, const sigset_t * sigmask) __attribute__((weak));
+}
+
QT_END_NAMESPACE
#endif //Q_OS_NACL
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 2df48cff34..0d0a97f82e 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -712,7 +712,7 @@ void QLibraryPrivate::updatePluginState()
}
#endif
-#if !defined (Q_OS_NACL)
+#if !defined (Q_OS_NACL) || defined (Q_OS_NACL_EMSCRIPTEN)
if (!pHnd) {
// scan for the plugin metadata without loading
success = findPatternUnloaded(fileName, this);
diff --git a/src/corelib/plugin/qplugin.h b/src/corelib/plugin/qplugin.h
index 9b3725a718..9af1629a13 100644
--- a/src/corelib/plugin/qplugin.h
+++ b/src/corelib/plugin/qplugin.h
@@ -40,7 +40,6 @@
QT_BEGIN_NAMESPACE
-
#ifndef Q_EXTERN_C
# ifdef __cplusplus
# define Q_EXTERN_C extern "C"
@@ -71,7 +70,20 @@ Q_DECLARE_TYPEINFO(QStaticPlugin, Q_PRIMITIVE_TYPE);
void Q_CORE_EXPORT qRegisterStaticPluginFunction(QStaticPlugin staticPlugin);
-#ifdef Q_OS_PNACL
+#if defined(Q_OS_NACL_EMSCRIPTEN)
+// It is important that the metadata is aligned in Emscripten because we are
+// not allowed to read unaligned data in JS/Emscripten.
+// Without this, importing static plugins will randomly fail because reading
+// the offset 'size' value in QLibraryPrivate::fromRawMetaData is undefined behavior.
+// For this purpose, aligning to 32 bits would suffice.
+// Using 64 bits is probably overkill, but should ensure that this problem doesn't
+// surface in other parts of the code.
+
+// TODO Do we need "section" and "used" attributes on Emscripten?
+// TODO Should we reduce alignment to 32 bits?
+# define QT_PLUGIN_METADATA_SECTION \
+ __attribute__ ((section (".qtmetadata"))) __attribute__((used)) __attribute__((aligned(64)))
+#elif defined(Q_OS_PNACL)
// PNaCl does not support "section":
// "Variable _ZL17qt_pluginMetaData has disallowed "section" attribute"
// PNaCl is Q_CC_CLANG. TODO: should it not set Q_OF_ELF?
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 14dc72a1f5..6e93e3b0d7 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -271,6 +271,12 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
void QMutex::unlock() Q_DECL_NOTHROW
{
+ // TODO replace this with using pthread stubs instead
+ // Note: Defining QT_NO_THREAD won't work because too many
+ // Qt internals (QFuture, QThreadPool, etc.) depend on threads
+#if defined(Q_OS_NACL_EMSCRIPTEN) && !defined(Q_OS_NACL_EMSCRIPTEN_PTHREADS)
+ return;
+#endif
QMutexData *current;
if (fastTryUnlock(current))
return;
diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp
index 74e0d68f94..abb02d77ae 100644
--- a/src/corelib/thread/qmutex_unix.cpp
+++ b/src/corelib/thread/qmutex_unix.cpp
@@ -70,6 +70,10 @@ QMutexPrivate::~QMutexPrivate()
bool QMutexPrivate::wait(int timeout)
{
+ // TODO Emscripten specialization could perhaps be replaced with pthread stubs
+#if defined(Q_OS_NACL_EMSCRIPTEN) && !defined(Q_OS_NACL_EMSCRIPTEN_PTHREADS)
+ return false;
+#endif
report_error(pthread_mutex_lock(&mutex), "QMutex::lock", "mutex lock");
int errorCode = 0;
while (!wakeup) {
diff --git a/src/corelib/thread/qwaitcondition_unix.cpp b/src/corelib/thread/qwaitcondition_unix.cpp
index b531707dd2..19c816475e 100644
--- a/src/corelib/thread/qwaitcondition_unix.cpp
+++ b/src/corelib/thread/qwaitcondition_unix.cpp
@@ -114,6 +114,10 @@ public:
int wait_relative(unsigned long time)
{
+ // TODO Emscripten specialization could perhaps be replaced with pthread stubs
+#if defined(Q_OS_NACL_EMSCRIPTEN) && !defined(Q_OS_NACL_EMSCRIPTEN_PTHREADS)
+ return 0;
+#endif
timespec ti;
#ifdef Q_OS_ANDROID
if (local_cond_timedwait_relative) {
@@ -128,6 +132,10 @@ public:
bool wait(unsigned long time)
{
+ // TODO Emscripten specialization could perhaps be replaced with pthread stubs
+#if defined(Q_OS_NACL_EMSCRIPTEN) && !defined(Q_OS_NACL_EMSCRIPTEN_PTHREADS)
+ return true;
+#endif
int code;
forever {
if (time != ULONG_MAX) {
@@ -194,6 +202,11 @@ void QWaitCondition::wakeAll()
bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
{
+ // TODO Emscripten specialization could perhaps be replaced with pthread stubs
+#if defined(Q_OS_NACL_EMSCRIPTEN) && !defined(Q_OS_NACL_EMSCRIPTEN_PTHREADS)
+ return true;
+#endif
+
if (! mutex)
return false;
if (mutex->isRecursive()) {
@@ -214,6 +227,10 @@ bool QWaitCondition::wait(QMutex *mutex, unsigned long time)
bool QWaitCondition::wait(QReadWriteLock *readWriteLock, unsigned long time)
{
+ // TODO Emscripten specialization could perhaps be replaced with pthread stubs
+#if defined(Q_OS_NACL_EMSCRIPTEN) && !defined(Q_OS_NACL_EMSCRIPTEN_PTHREADS)
+ return true;
+#endif
if (!readWriteLock || readWriteLock->d->accessCount == 0)
return false;
if (readWriteLock->d->accessCount < -1) {
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 971d0c0cec..137988ce39 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -640,6 +640,10 @@ int ffsll(quint64 i)
# define ffsll __builtin_ffsll
#endif
+#if defined(Q_OS_NACL_NEWLIB) || defined(Q_OS_NACL_EMSCRIPTEN)
+# define ffsll __builtin_ffsll
+#endif
+
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
Q_CORE_EXPORT QBasicAtomicInteger<quint64> qt_cpu_features[1] = { Q_BASIC_ATOMIC_INITIALIZER(0) };
#else
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
index ca002642d8..6699b38b39 100644
--- a/src/gui/opengl/qopenglfunctions.h
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -565,7 +565,7 @@ struct QOpenGLFunctionsPrivate
// GLES2 + OpenGL1 common subset
-#ifdef Q_OS_NACL
+#if defined(Q_OS_NACL) && !defined(Q_OS_NACL_EMSCRIPTEN)
#include "qopenglfunctions_nacl.h"
#else
inline void QOpenGLFunctions::glBindTexture(GLenum target, GLuint texture)
diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp
index 1ef0b3ef17..6089a3ed27 100644
--- a/src/gui/opengl/qopengltexturehelper.cpp
+++ b/src/gui/opengl/qopengltexturehelper.cpp
@@ -167,6 +167,62 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
TexSubImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(GetProcAddress(handle, QByteArrayLiteral("glTexSubImage2D")));
TexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(GetProcAddress(handle, QByteArrayLiteral("glTexSubImage1D")));
+#elif defined(Q_OS_NACL_EMSCRIPTEN)
+ GetIntegerv = ::glGetIntegerv;
+ GetBooleanv = ::glGetBooleanv;
+ PixelStorei = ::glPixelStorei;
+ GetTexLevelParameteriv = 0;
+ GetTexLevelParameterfv = 0;
+ GetTexParameteriv = ::glGetTexParameteriv;
+ GetTexParameterfv = ::glGetTexParameterfv;
+ GetTexImage = 0;
+ TexImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(::glTexImage2D);
+ TexImage1D = 0;
+ TexParameteriv = ::glTexParameteriv;
+ TexParameteri = ::glTexParameteri;
+ TexParameterfv = ::glTexParameterfv;
+ TexParameterf = ::glTexParameterf;
+
+ // OpenGL 1.1
+ GenTextures = ::glGenTextures;
+ DeleteTextures = ::glDeleteTextures;
+ BindTexture = ::glBindTexture;
+ TexSubImage2D = ::glTexSubImage2D;
+ TexSubImage1D = 0;
+
+ // OpenGL 1.3
+ GetCompressedTexImage = 0;
+ CompressedTexSubImage1D = 0;
+ CompressedTexSubImage2D = ::glCompressedTexSubImage2D;
+ CompressedTexImage1D = 0;
+ CompressedTexImage2D = ::glCompressedTexImage2D;
+ ActiveTexture = ::glActiveTexture;
+
+ // OpenGL 3.0
+ GenerateMipmap = ::glGenerateMipmap;
+
+ // OpenGL 3.2
+ TexImage3DMultisample = 0;
+ TexImage2DMultisample = 0;
+
+ // OpenGL 4.2
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (ctx->format().majorVersion() >= 3) {
+ // OpenGL ES 3.0+ has immutable storage for 2D and 3D at least.
+ QOpenGLES3Helper *es3 = static_cast<QOpenGLExtensions *>(ctx->functions())->gles3Helper();
+ TexStorage3D = es3->TexStorage3D;
+ TexStorage2D = es3->TexStorage2D;
+ } else {
+ TexStorage3D = 0;
+ TexStorage2D = 0;
+ }
+ TexStorage1D = 0;
+
+ // OpenGL 4.3
+ TexStorage3DMultisample = 0;
+ TexStorage2DMultisample = 0;
+ TexBufferRange = 0;
+ TextureView = 0;
#elif defined(QT_OPENGL_ES_2)
// Here we are targeting OpenGL ES 2.0+ only. This is likely using EGL, where,
// similarly to WGL, non-extension functions (i.e. any function that is part of the
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/audio.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/audio.js
index 96b21e99f3..5538088eca 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/audio.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/audio.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
var isAudioSupported = function() {
@@ -186,3 +189,5 @@
], isAudioSupported);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/base.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/base.js
index 4da0eb52d0..e8b2049e6a 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/base.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/base.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
var DoLog = function(level, value) {
// TODO enum?
@@ -111,6 +114,65 @@
Messaging_PostMessage
]);
+ registerInterface("PPB_Messaging;1.2", [
+ Messaging_PostMessage
+ ]);
+
+ var MessageLoop_InstanceHandle = function(instance) {
+ // console.warn("MessageLoop_InstanceHandle is not implemented")
+ console.log("Returning MessageLoop instance")
+ return 1;
+ };
+
+ var MessageLoop_GetForMainThread = function() {
+ // console.warn("MessageLoop_GetForMainThread is not implemented")
+ console.log("Returning MessageLoop instance main")
+ return 1;
+ };
+
+ var MessageLoop_GetCurrent = function() {
+ // console.warn("MessageLoop_GetCurrent is not implemented")
+ console.log("Returning MessageLoop instance current")
+ return 1;
+ };
+
+ var MessageLoop_Run = function(resource) {
+ // console.warn("MessageLoop_Run is not implemented " + resource)
+ console.log("MessageLoop_Run called")
+ return 1;
+ };
+
+ var MessageLoop_AttachToCurrentThread = function(resource) {
+ // console.warn("MessageLoop_Run is not implemented " + resource)
+ console.log("Attach!")
+ return 1;
+ };
+
+ var MessageLoop_PostWork = function(resource, callback, delay_ms) {
+ // console.log("MessageLoop_PostWork received")
+ var c = glue.getCompletionCallback(callback);
+ Module.requestAnimationFrame(function() {
+ // console.log("MessageLoop_PostWork callback being called!")
+ c(0);
+ });
+ return 0;
+ };
+
+ var MessageLoop_PostQuit = function(resource, should_destroy) {
+ console.warn("MessageLoop_PostQuit is not implemented " + resource)
+ return 0;
+ };
+
+ registerInterface("PPB_MessageLoop;1.0", [
+ MessageLoop_InstanceHandle,
+ MessageLoop_GetForMainThread,
+ MessageLoop_GetCurrent,
+ MessageLoop_AttachToCurrentThread,
+ MessageLoop_Run,
+ MessageLoop_PostWork,
+ MessageLoop_PostQuit,
+ ]);
+
var Var_AddRef = function(v) {
if (glue.isRefCountedVarType(glue.getVarType(v))) {
resources.addRef(glue.getVarUID(v));
@@ -407,3 +469,5 @@
]);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/common.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/common.js
new file mode 100644
index 0000000000..caf4f54733
--- /dev/null
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/common.js
@@ -0,0 +1,415 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Javascript module pattern:
+// see http://en.wikipedia.org/wiki/Unobtrusive_JavaScript#Namespaces
+// In essence, we define an anonymous function which is immediately called and
+// returns a new object. The new object contains only the exported definitions;
+// all other definitions in the anonymous function are inaccessible to external
+// code.
+var common = (function () {
+
+ var addListener = function(elt, event_name, callback) {
+ if (elt.addEventListener) {
+ elt.addEventListener(event_name, callback, false);
+ } else {
+ elt.attachEvent('on' + event_name, callback);
+ }
+ };
+
+ var getImageDataBuffer = function(imageData) {
+ var buffer = imageData.data.buffer;
+ // IE support
+ if(buffer === undefined) {
+ buffer = new ArrayBuffer(imageData.data.length);
+ view = new Uint8Array(buffer);
+ for (var i = 0; i < imageData.data.length; i++) {
+ view[i] = imageData.data[i];
+ }
+ }
+ return buffer;
+ }
+
+ nacl.createInstance = function(config) {
+ var variant = config.module;
+ var e;
+ var width = config.width;
+ var height = config.height;
+ var type = variant.type;
+ if (type == "pnacl") {
+ e = nacl.createEmbedInstance(variant.url, nacl.pnaclMimeType, width, height);
+ } else if (type == "emscripten") {
+ e = nacl.createEmscriptenInstance(variant.url, width, height);
+ } else if (type == "nacl") {
+ e = nacl.createEmbedInstance(variant.url, nacl.naclMimeType, width, height);
+ } else if (type == "host") {
+ e = nacl.createEmbedInstance("bogusURL", nacl.mimetype, width, height);
+ } else {
+ throw new Error("Unknown variant type " + type);
+ }
+ if (config.init) {
+ config.init(e);
+ }
+ if (config.progress) {
+ e.addEventListener('progress', config.progress);
+ }
+ if (config.load) {
+ e.addEventListener('load', config.load);
+ }
+ if (config.error) {
+ e.addEventListener('error', config.error);
+ }
+ config.insert.appendChild(e);
+ e.load();
+ return e;
+ };
+
+ var loadStart;
+
+ /**
+ * Create the Native Client <embed> element as a child of the DOM element
+ * named "listener".
+ *
+ * @param {string} name The name of the example.
+ * @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc.
+ * @param {string} path Directory name where .nmf file can be found.
+ * @param {number} width The width to create the plugin.
+ * @param {number} height The height to create the plugin.
+ * @param {Object} optional dictionary of args to send to DidCreateInstance
+ */
+ function createNaClModule(name, tool, path, width, height, args) {
+ loadStart = new Date();
+
+ var isRelease = path.toLowerCase().indexOf('release') != -1;
+
+ var progress = document.createElement('progress');
+ progress.style.width = '480px';
+
+ var modules = {
+ "pnacl": {
+ type: "pnacl",
+ url: path + '/' + name + '.nmf',
+ },
+ "nacl": {
+ type: "nacl",
+ url: path + '/' + name + '.nmf',
+ },
+ "emscripten": {
+ type: "emscripten",
+ url: path + '/' + name + '.js',
+ },
+ "host": {
+ type: "host",
+ mimetype: 'application/x-ppapi-' + (isRelease ? 'release' : 'debug'),
+ }
+ };
+
+ var moduleEl = nacl.createInstance({
+ module: modules[tool],
+ width: width,
+ height: height,
+ insert: document.getElementById('listener'),
+ init: function(e) {
+ e.setAttribute('name', 'nacl_module');
+ e.setAttribute('id', 'nacl_module');
+ e.setAttribute('path', path);
+ // Add any optional arguments
+ if (args) {
+ for (var key in args) {
+ e.setAttribute(key, args[key])
+ }
+ }
+ },
+ progress: function(evt) {
+ var loadPercent = -1.0;
+ progress.max = 100;
+ if (evt.lengthComputable && evt.total > 0) {
+ loadPercent = evt.loaded / evt.total * 100.0;
+ }
+ progress.value = loadPercent;
+ },
+ load: function(evt) {
+ progress.value = 100;
+ document.getElementById('listener').removeChild(progress);
+ },
+ error: function(evt) {
+ progress.value = 100;
+ document.getElementById('listener').removeChild(progress);
+ },
+ });
+
+ if (tool == 'pnacl' && !nacl.hasPNaCl()) {
+ updateStatus('PNaCl requires Chrome 31 or newer.');
+ } else if (tool == 'nacl' && !nacl.hasNaCl()) {
+ updateStatus('NaCl requires Chrome.');
+ } else {
+ document.getElementById('listener').appendChild(progress);
+ }
+
+ // Host plugins don't send a moduleDidLoad message. We'll fake it
+ // here.
+ var isHost = tool == 'win' || tool == 'linux' || tool == 'mac' || tool == 'host';
+ if (isHost) {
+ window.setTimeout(function () {
+ var evt = document.createEvent('Event');
+ evt.initEvent('load', true, true); // bubbles, cancelable
+ moduleEl.dispatchEvent(evt);
+ }, 100); // 100 ms
+ }
+ return moduleEl;
+ }
+
+ /**
+ * Add the default "load" and "message" event listeners to the element with
+ * id "listener".
+ *
+ * The "load" event is sent when the module is successfully loaded. The
+ * "message" event is sent when the naclModule posts a message using
+ * PPB_Messaging.PostMessage() (in C) or pp::Instance().PostMessage() (in
+ * C++).
+ */
+ function attachDefaultListeners() {
+ var listenerDiv = document.getElementById('listener');
+ listenerDiv.addEventListener('load', moduleDidLoad, true);
+ listenerDiv.addEventListener('message', handleMessage, true);
+ listenerDiv.addEventListener('crash', handleCrash, true);
+ if (typeof window.attachListeners !== 'undefined') {
+ window.attachListeners();
+ }
+ }
+
+
+ /**
+ * Called when the Browser can not communicate with the Module
+ *
+ * This event listener is registered in attachDefaultListeners above.
+ */
+ function handleCrash(event) {
+ updateStatus('module crashed')
+ if (typeof window.handleCrash !== 'undefined') {
+ window.handleCrash(common.naclModule.lastError);
+ }
+ }
+
+ /**
+ * Called when the NaCl module is loaded.
+ *
+ * This event listener is registered in attachDefaultListeners above.
+ */
+ function moduleDidLoad() {
+ common.naclModule = document.getElementById('nacl_module');
+ updateStatus('loaded');
+ console.log("Create instance: " + (new Date()-loadStart) + " ms");
+
+ if (typeof window.moduleDidLoad !== 'undefined') {
+ window.moduleDidLoad();
+ }
+ }
+
+ /**
+ * Hide the NaCl module's embed element.
+ *
+ * We don't want to hide by default; if we do, it is harder to determine that
+ * a plugin failed to load. Instead, call this function inside the example's
+ * "moduleDidLoad" function.
+ *
+ */
+ function hideModule() {
+ // Setting common.naclModule.style.display = "None" doesn't work; the
+ // module will no longer be able to receive postMessages.
+ common.naclModule.style.height = "0";
+ }
+
+ /**
+ * Return true when |s| starts with the string |prefix|.
+ *
+ * @param {string} s The string to search.
+ * @param {string} prefix The prefix to search for in |s|.
+ */
+ function startsWith(s, prefix) {
+ // indexOf would search the entire string, lastIndexOf(p, 0) only checks at
+ // the first index. See: http://stackoverflow.com/a/4579228
+ return s.lastIndexOf(prefix, 0) === 0;
+ }
+
+ /** Maximum length of logMessageArray. */
+ var kMaxLogMessageLength = 20;
+
+ /** An array of messages to display in the element with id "log". */
+ var logMessageArray = [];
+
+ /**
+ * Add a message to an element with id "log".
+ *
+ * This function is used by the default "log:" message handler.
+ *
+ * @param {string} message The message to log.
+ */
+ function logMessage(message) {
+ logMessageArray.push(message);
+ if (logMessageArray.length > kMaxLogMessageLength)
+ logMessageArray.shift();
+
+ document.getElementById('log').textContent = logMessageArray.join('');
+ console.log(message)
+ }
+
+ /**
+ */
+ var defaultMessageTypes = {
+ 'alert': alert,
+ 'log': logMessage
+ };
+
+ /**
+ * Called when the NaCl module sends a message to JavaScript (via
+ * PPB_Messaging.PostMessage())
+ *
+ * This event listener is registered in createNaClModule above.
+ *
+ * @param {Event} message_event A message event. message_event.data contains
+ * the data sent from the NaCl module.
+ */
+ function handleMessage(message_event) {
+ if (typeof message_event.data === 'string') {
+ for (var type in defaultMessageTypes) {
+ if (defaultMessageTypes.hasOwnProperty(type)) {
+ if (startsWith(message_event.data, type + ':')) {
+ func = defaultMessageTypes[type];
+ func(message_event.data.slice(type.length + 1));
+ return;
+ }
+ }
+ }
+ }
+
+ if (typeof window.handleMessage !== 'undefined') {
+ window.handleMessage(message_event);
+ }
+ }
+
+ /**
+ * Called when the DOM content has loaded; i.e. the page's document is fully
+ * parsed. At this point, we can safely query any elements in the document via
+ * document.querySelector, document.getElementById, etc.
+ *
+ * @param {string} name The name of the example.
+ * @param {string} tool The name of the toolchain, e.g. "glibc", "newlib" etc.
+ * @param {string} path Directory name where .nmf file can be found.
+ * @param {number} width The width to create the plugin.
+ * @param {number} height The height to create the plugin.
+ */
+ function domContentLoaded(name, tool, path, width, height) {
+ // If the page loads before the Native Client module loads, then set the
+ // status message indicating that the module is still loading. Otherwise,
+ // do not change the status message.
+ updateStatus('page loaded');
+ if (common.naclModule == null) {
+ updateStatus('creating ' + tool + ' embed')
+
+ // We use a non-zero sized embed to give Chrome space to place the bad
+ // plug-in graphic, if there is a problem.
+ width = typeof width !== 'undefined' ? width : 200;
+ height = typeof height !== 'undefined' ? height : 200;
+ attachDefaultListeners();
+ createNaClModule(name, tool, path, width, height);
+ } else {
+ // It's possible that the Native Client module onload event fired
+ // before the page's onload event. In this case, the status message
+ // will reflect 'SUCCESS', but won't be displayed. This call will
+ // display the current message.
+ updateStatus('waiting');
+ }
+ }
+
+ /** Saved text to display in the element with id 'statusField'. */
+ var statusText = 'NO-STATUSES';
+
+ /**
+ * Set the global status message. If the element with id 'statusField'
+ * exists, then set its HTML to the status message as well.
+ *
+ * @param {string} opt_message The message to set. If null or undefined, then
+ * set element 'statusField' to the message from the last call to
+ * updateStatus.
+ */
+ function updateStatus(opt_message) {
+ if (opt_message) {
+ statusText = opt_message;
+ }
+ var statusField = document.getElementById('statusField');
+ if (statusField) {
+ statusField.innerHTML = statusText;
+ }
+ }
+
+ // The symbols to export.
+ return {
+ /** A reference to the NaCl module, once it is loaded. */
+ naclModule: null,
+
+ addListener: addListener,
+ getImageDataBuffer: getImageDataBuffer,
+ attachDefaultListeners: attachDefaultListeners,
+ domContentLoaded: domContentLoaded,
+ createNaClModule: createNaClModule,
+ hideModule: hideModule,
+ logMessage: logMessage,
+ updateStatus: updateStatus
+ };
+
+}());
+
+// Listen for the DOM content to be loaded. This event is fired when parsing of
+// the page's document has finished.
+//common.addListener(document, 'DOMContentLoaded', function() {
+window.onload = function() {
+ var body = document.querySelector('body');
+
+ var loadFunction = common.domContentLoaded;
+ // The data-* attributes on the body can be referenced via body.dataset.
+ if (body.dataset && body.dataset.customLoad && typeof window.domContentLoaded !== 'undefined') {
+ loadFunction = window.domContentLoaded;
+ }
+
+ // From https://developer.mozilla.org/en-US/docs/DOM/window.location
+ var searchVars = {};
+ if (window.location.search.length > 1) {
+ var pairs = window.location.search.substr(1).split("&");
+ for (var key_ix = 0; key_ix < pairs.length; key_ix++) {
+ var keyValue = pairs[key_ix].split("=");
+ searchVars[unescape(keyValue[0])] =
+ keyValue.length > 1 ? unescape(keyValue[1]) : "";
+ }
+ }
+ if (loadFunction) {
+ var name = body.getAttribute("data-name");
+ var tc = body.getAttribute("data-tc");
+ var path = body.getAttribute("data-path");
+ var width = body.getAttribute("data-width") || undefined;
+ var height = body.getAttribute("data-height") || undefined;
+
+ var toolchains = (body.getAttribute("data-tools") || tc || "emscripten newlib pnacl").split(' ');
+ var configs = (body.getAttribute("data-configs") || "Debug Release").split(' ');
+
+ var tc = toolchains.indexOf(searchVars.tc) !== -1 ?
+ searchVars.tc : toolchains[0];
+ var config = configs.indexOf(searchVars.config) !== -1 ?
+ searchVars.config : configs[0];
+ path = path.replace('{tc}', tc).replace('{config}', config);
+
+ // The SDK uses the pnacl toolchain to compile nexes in Debug mode.
+ if (tc == 'pnacl' && config == 'Debug') {
+ tc = 'nacl';
+ }
+ if (tc == 'newlib') {
+ tc = 'nacl';
+ }
+ if (tc == 'win' || tc == 'linux' || tc == 'mac') {
+ tc = 'host';
+ }
+ loadFunction(name, tc, path, width, height);
+ }
+};
+//});
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/file.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/file.js
index ceb66652ac..c9faa1a5f4 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/file.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/file.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
var PP_FILESYSTEMTYPE_INVALID = 0;
@@ -381,3 +384,5 @@
]);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/gles.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/gles.js
index 8ae4deeb5e..f675c10195 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/gles.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/gles.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
// (GLenum) => void
@@ -53,6 +56,10 @@
if (_context === undefined) {
return;
}
+ if(buffer == 0) {
+ // TODO buffer = 0 should release previously bound buffers
+ return;
+ }
var _buffer = resources.resolve(buffer, BUFFER_RESOURCE);
if (_buffer === undefined) {
return;
@@ -67,6 +74,12 @@
if (_context === undefined) {
return;
}
+ if(framebuffer == 0) {
+ // framebuffer = 0 is the default framebuffer provided by the system
+ // and is translated to null in WebGL
+ _context.ctx.bindFramebuffer(target, null);
+ return;
+ }
var _framebuffer = coerceFramebuffer(framebuffer);
_context.ctx.bindFramebuffer(target, _framebuffer);
}
@@ -561,7 +574,48 @@
}
var OpenGLES2_GetProgramiv = function(context, program, pname, params) {
- throw "OpenGLES2_GetProgramiv not implemented";
+ if(pname == 35716 || pname == 35720) {
+ // 35716 = GL_INFO_LOG_LENGTH (0x8B84)
+ // 35720 = GL_SHADER_SOURCE_LENGTH (0x8B88)
+ // These are not allowed in WebGL, but are allowed in GLES.
+ // Return 0 so that legacy code thinks there is no log or source to print
+ var result = 0
+ setValue(params, result, 'i32');
+ return
+ }
+ var _context = resources.resolve(context, GRAPHICS_3D_RESOURCE);
+ if (_context === undefined) {
+ return 0;
+ }
+ var _program = resources.resolve(program, PROGRAM_RESOURCE);
+ if (_program === undefined) {
+ return 0;
+ }
+ var result = _context.ctx.getProgramParameter(_program.native, pname);
+ switch(pname) {
+ case _context.ctx.DELETE_STATUS:
+ setValue(params, result, 'i8');
+ break;
+ case _context.ctx.LINK_STATUS:
+ setValue(params, result, 'i8');
+ break;
+ case _context.ctx.VALIDATE_STATUS:
+ setValue(params, result, 'i8');
+ break;
+ case _context.ctx.ATTACHED_SHADERS:
+ setValue(params, result, 'i32');
+ break;
+ case _context.ctx.ACTIVE_ATTRIBUTES:
+ setValue(params, result, 'i32');
+ break;
+ case _context.ctx.ACTIVE_UNIFORMS:
+ setValue(params, result, 'i32');
+ break;
+ default:
+ console.warn("OpenGLES2_GetProgramiv unknown parameter type, assume i32")
+ setValue(params, result, 'i32');
+ break;
+ }
}
var OpenGLES2_GetProgramInfoLog = function(context, program, bufsize, length, infolog) {
@@ -573,7 +627,16 @@
}
var OpenGLES2_GetShaderiv = function(context, shader, pname, params) {
- throw "OpenGLES2_GetShaderiv not implemented";
+ var _context = resources.resolve(context, GRAPHICS_3D_RESOURCE);
+ if (_context === undefined) {
+ return 0;
+ }
+ var _shader = resources.resolve(shader, SHADER_RESOURCE);
+ if (_shader === undefined) {
+ return 0;
+ }
+ var result = _context.ctx.getShaderParameter(_shader.native, pname);
+ setValue(params, result, 'i32');
}
var OpenGLES2_GetShaderInfoLog = function(context, shader, bufsize, length, infolog) {
@@ -1091,11 +1154,21 @@
return;
}
var _value = HEAPF32.subarray((value>>2), (value>>2) + 16 * count);
+ // TODO: This is temporary to cast SharedFloat32Array to a Float32Array. Remove this once https://bugzilla.mozilla.org/show_bug.cgi?id=1205390 lands.
+ _value = new Float32Array(_value);
_context.ctx.uniformMatrix4fv(_location.native, transpose, _value);
}
// ppapi (GLuint) => void
// webgl (WebGLProgram) => void
var OpenGLES2_UseProgram = function(context, program) {
+ if(program === 0) {
+ // TODO Is useprogram(0) okay to call?
+ // OpenGLES2_UseProgram: Requested to use program 0. "
+ // This is not a defined operation in WebGL, but in legacy
+ // code it is a request to release the program.
+ // Here, nothing will be done when calling glUseProgram(0).
+ return
+ }
var _context = resources.resolve(context, GRAPHICS_3D_RESOURCE);
if (_context === undefined) {
return;
@@ -1386,3 +1459,5 @@
// UniformMatrix2fv: Cannot deal with overloads
// UniformMatrix3fv: Cannot deal with overloads
// 94:48
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/gles_ext.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/gles_ext.js
index 9dfc7f4bf3..f35b6b038d 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/gles_ext.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/gles_ext.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
// PPB_OpenGLES2InstancedArrays
@@ -212,5 +215,30 @@
OpenGLES2Query_GetQueryivEXT,
OpenGLES2Query_GetQueryObjectuivEXT,
]);
+
+ var OpenGLES2VertexArrayObject_BindVertexArrayOES = function(context, x, y, width, height) {
+ throw "OpenGLES2_BindVertexArrayOES is not implemented"
+ }
+ var OpenGLES2VertexArrayObject_DeleteVertexArrayOES = function(context, x, y, width, height) {
+ throw "OpenGLES2_BindVertexArrayOES is not implemented"
+ }
+ var OpenGLES2VertexArrayObject_GenVertexArrayOES = function(context, x, y, width, height) {
+ throw "OpenGLES2_BindVertexArrayOES is not implemented"
+ }
+ var OpenGLES2VertexArrayObject_IsVertexArrayOES = function(context, x, y, width, height) {
+ throw "OpenGLES2_BindVertexArrayOES is not implemented"
+ }
+
+ registerInterface("PPB_OpenGLES2VertexArrayObject;1.0", [
+ OpenGLES2VertexArrayObject_BindVertexArrayOES,
+ OpenGLES2VertexArrayObject_DeleteVertexArrayOES,
+ OpenGLES2VertexArrayObject_GenVertexArrayOES,
+ OpenGLES2VertexArrayObject_IsVertexArrayOES
+ ]);
+
+ registerInterface("PPB_OpenGLES2DrawBuffers(Dev);1.0", [
+ ]);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_2d.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_2d.js
index e3d5918e04..e619eb2444 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_2d.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_2d.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
var Graphics2D_Create = function(instance, size_ptr, is_always_opaque) {
@@ -386,3 +389,5 @@
ImageData_Unmap
]);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_3d.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_3d.js
index 42e62d809d..ffc4c376d4 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_3d.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/graphics_3d.js
@@ -2,9 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
var getContext = function(c, params) {
+ // TODO we bypass this with Browser.createContext, except for in the test
return c.getContext('webgl', params) || c.getContext("experimental-webgl", params);
};
@@ -94,7 +98,7 @@
return resources.register(GRAPHICS_3D_RESOURCE, {
canvas: canvas,
bound: false,
- ctx: getContext(canvas, {
+ ctx: Browser.createContext(canvas, true, true, {
"alpha": alpha_size > 0,
"depth": depth_size > 0,
"stencil": stencil_size > 0,
@@ -143,8 +147,10 @@
var Graphics3D_SwapBuffers = function(context, callback) {
// TODO double buffering.
+ // console.log("Graphics3D_SwapBuffers request received")
var c = glue.getCompletionCallback(callback);
Module.requestAnimationFrame(function() {
+ // console.log("Graphics3D_SwapBuffers calling back!")
c(0);
});
};
@@ -162,3 +168,5 @@
return !!getContext(document.createElement("canvas"));
});
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/input_events.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/input_events.js
index 274212aa1f..1ce29bba3c 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/input_events.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/input_events.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
//Enums copied from ppb_input_event.h
@@ -191,7 +194,8 @@
movement: GetMovement(event),
delta: GetWheelScroll(event),
scrollByPage: event.deltaMode === 2,
- keyCode: event.keyCode
+ keyCode: event.keyCode,
+ charCode: event.charCode
});
var rval = _HandleInputEvent(instance, obj_uid);
@@ -426,16 +430,33 @@
return res.keyCode;
};
+ var KeyboardInputEvent_GetCode = function(event) {
+ throw "KeyboardInputEvent_GetCode not implemented";
+ };
+
var KeyboardInputEvent_GetCharacterText = function(ptr, event) {
- // TODO(grosse): Find way to implement this
- glue.jsToMemoryVar(undefined, ptr);
+ var res = resources.resolve(event, INPUT_EVENT_RESOURCE);
+ if (res === undefined) {
+ return 0;
+ }
+ glue.jsToMemoryVar(String.fromCharCode(res.charCode), ptr);
};
- registerInterface("PPB_KeyboardInputEvent;1.0", [
- KeyboardInputEvent_Create,
- KeyboardInputEvent_IsKeyboardInputEvent,
- KeyboardInputEvent_GetKeyCode,
- KeyboardInputEvent_GetCharacterText
- ]);
+ registerInterface("PPB_KeyboardInputEvent;1.0", [
+ KeyboardInputEvent_Create,
+ KeyboardInputEvent_IsKeyboardInputEvent,
+ KeyboardInputEvent_GetKeyCode,
+ KeyboardInputEvent_GetCharacterText
+ ]);
+
+ registerInterface("PPB_KeyboardInputEvent;1.2", [
+ KeyboardInputEvent_Create,
+ KeyboardInputEvent_IsKeyboardInputEvent,
+ KeyboardInputEvent_GetKeyCode,
+ KeyboardInputEvent_GetCharacterText,
+ KeyboardInputEvent_GetCode,
+ ]);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/mouse_lock.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/mouse_lock.js
index fc25df1cbf..09442b8bef 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/mouse_lock.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/mouse_lock.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
var MouseLock_LockMouse = function(instance, callback) {
@@ -102,3 +105,5 @@
});
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/ppapi_preamble.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/ppapi_preamble.js
index 910eb70b30..ea856dfe41 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/ppapi_preamble.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/ppapi_preamble.js
@@ -5,6 +5,13 @@
// TODO(ncbray): re-enable once Emscripten stops including code with octal values.
//"use strict";
+var doCreateInstance = doCreateInstance || function () {
+ console.log("Please call QtLoader.load() instead of loading your application script.")
+}
+
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
var clamp = function(value, min, max) {
if (value < min) {
return min;
@@ -96,6 +103,8 @@ var ARRAY_RESOURCE = 21;
var DICTIONARY_RESOURCE = 22;
var WEB_SOCKET_RESOURCE = 23;
+var MESSAGE_LOOP_RESOURCE = 24;
+
var ResourceManager = function() {
this.lut = {};
this.uid = 1;
@@ -296,10 +305,10 @@ var createInterface = function(name, functions) {
interfaces[name] = ptr;
};
-var Module = {
- "noInitialRun": true,
- "noExitRuntime": true,
- "preInit": function() {
+var Module = Module || {};
+Module["noInitialRun"] = true;
+Module["noExitRuntime"] = true;
+Module["onRuntimeInitialized"] = function() {
for (var i = 0; i < declaredInterfaces.length; i++) {
var inf = declaredInterfaces[i];
if (inf.supported === undefined || inf.supported()) {
@@ -309,7 +318,7 @@ var Module = {
}
}
declaredInterfaces = [];
- }
+ doCreateInstance();
};
var CreateInstance = function(width, height, shadow_instance) {
@@ -983,3 +992,5 @@ var _GetBrowserInterface = function(interface_name) {
}
return inf;
};
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/testing.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/testing.js
index 79b4fc08c7..21ef601a5f 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/testing.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/testing.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
var Testing_Dev_ReadImageData = function(device_context_2d, image, top_left) {
@@ -53,3 +56,5 @@
Testing_Dev_SetMinimumArrayBufferSizeForShmem,
]);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/url_loader.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/url_loader.js
index af40696cc8..58f532c054 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/url_loader.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/url_loader.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
// Canonicalize the URL using the DOM.
@@ -369,3 +372,5 @@
]);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/view.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/view.js
index 423539fc6b..8ceec3a321 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/view.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/view.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
var View_IsView = function(resource) {
return resources.is(resource, VIEW_RESOURCE);
@@ -88,4 +91,17 @@
View_GetDeviceScale,
View_GetCSSScale,
]);
+
+ registerInterface("PPB_View;1.2", [
+ View_IsView,
+ View_GetRect,
+ View_IsFullscreen,
+ View_IsVisible,
+ View_IsPageVisible,
+ View_GetClipRect,
+ View_GetDeviceScale,
+ View_GetCSSScale,
+ ]);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/3rdparty/pepper.js/web_socket.js b/src/plugins/platforms/pepper/3rdparty/pepper.js/web_socket.js
index 732efd9f88..8eccb30e5b 100644
--- a/src/plugins/platforms/pepper/3rdparty/pepper.js/web_socket.js
+++ b/src/plugins/platforms/pepper/3rdparty/pepper.js/web_socket.js
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+var ENVIRONMENT_IS_PTHREAD; // is set to true in pthread-main.js if we are in a worker
+if(!ENVIRONMENT_IS_PTHREAD) {
+
(function() {
/*
@@ -322,3 +325,5 @@ http://creativecommons.org/publicdomain/zero/1.0/legalcode
]);
})();
+
+}
diff --git a/src/plugins/platforms/pepper/pepper.js.pri b/src/plugins/platforms/pepper/pepper.js.pri
index 0b3a557f81..43472e3a76 100644
--- a/src/plugins/platforms/pepper/pepper.js.pri
+++ b/src/plugins/platforms/pepper/pepper.js.pri
@@ -2,8 +2,12 @@
PPAPI_CPP_SOURCE= $$(NACL_SDK_ROOT)/src/ppapi_cpp
SOURCES += \
$${PPAPI_CPP_SOURCE}/array_output.cc \
- $${PPAPI_CPP_SOURCE}/audio.cc \
+ $${PPAPI_CPP_SOURCE}/audio_buffer.cc \
$${PPAPI_CPP_SOURCE}/audio_config.cc \
+ $${PPAPI_CPP_SOURCE}/audio_encoder.cc \
+ $${PPAPI_CPP_SOURCE}/audio.cc \
+ $${PPAPI_CPP_SOURCE}/compositor_layer.cc \
+ $${PPAPI_CPP_SOURCE}/compositor.cc \
$${PPAPI_CPP_SOURCE}/core.cc \
$${PPAPI_CPP_SOURCE}/cursor_control_dev.cc \
$${PPAPI_CPP_SOURCE}/directory_entry.cc \
@@ -14,14 +18,16 @@ SOURCES += \
$${PPAPI_CPP_SOURCE}/font_dev.cc \
$${PPAPI_CPP_SOURCE}/fullscreen.cc \
$${PPAPI_CPP_SOURCE}/graphics_2d.cc \
- $${PPAPI_CPP_SOURCE}/graphics_3d.cc \
$${PPAPI_CPP_SOURCE}/graphics_3d_client.cc \
+ $${PPAPI_CPP_SOURCE}/graphics_3d.cc \
$${PPAPI_CPP_SOURCE}/host_resolver.cc \
$${PPAPI_CPP_SOURCE}/image_data.cc \
$${PPAPI_CPP_SOURCE}/input_event.cc \
- $${PPAPI_CPP_SOURCE}/instance.cc \
$${PPAPI_CPP_SOURCE}/instance_handle.cc \
+ $${PPAPI_CPP_SOURCE}/instance.cc \
$${PPAPI_CPP_SOURCE}/lock.cc \
+ $${PPAPI_CPP_SOURCE}/media_stream_audio_track.cc \
+ $${PPAPI_CPP_SOURCE}/media_stream_video_track.cc \
$${PPAPI_CPP_SOURCE}/memory_dev.cc \
$${PPAPI_CPP_SOURCE}/message_loop.cc \
$${PPAPI_CPP_SOURCE}/module.cc \
@@ -38,7 +44,6 @@ SOURCES += \
$${PPAPI_CPP_SOURCE}/rect.cc \
$${PPAPI_CPP_SOURCE}/resource.cc \
$${PPAPI_CPP_SOURCE}/scriptable_object_deprecated.cc \
- $${PPAPI_CPP_SOURCE}/selection_dev.cc \
$${PPAPI_CPP_SOURCE}/simple_thread.cc \
$${PPAPI_CPP_SOURCE}/tcp_socket.cc \
$${PPAPI_CPP_SOURCE}/text_input_controller.cc \
@@ -47,17 +52,18 @@ SOURCES += \
$${PPAPI_CPP_SOURCE}/url_loader.cc \
$${PPAPI_CPP_SOURCE}/url_request_info.cc \
$${PPAPI_CPP_SOURCE}/url_response_info.cc \
- $${PPAPI_CPP_SOURCE}/var.cc \
- $${PPAPI_CPP_SOURCE}/var_array.cc \
$${PPAPI_CPP_SOURCE}/var_array_buffer.cc \
+ $${PPAPI_CPP_SOURCE}/var_array.cc \
$${PPAPI_CPP_SOURCE}/var_dictionary.cc \
- $${PPAPI_CPP_SOURCE}/view.cc \
+ $${PPAPI_CPP_SOURCE}/var.cc \
+ $${PPAPI_CPP_SOURCE}/video_decoder.cc \
+ $${PPAPI_CPP_SOURCE}/video_encoder.cc \
+ $${PPAPI_CPP_SOURCE}/video_frame.cc \
$${PPAPI_CPP_SOURCE}/view_dev.cc \
- $${PPAPI_CPP_SOURCE}/websocket.cc \
+ $${PPAPI_CPP_SOURCE}/view.cc \
$${PPAPI_CPP_SOURCE}/websocket_api.cc \
- $${PPAPI_CPP_SOURCE}/zoom_dev.cc \
- $${PPAPI_CPP_SOURCE}/media_stream_video_track.cc \
- $${PPAPI_CPP_SOURCE}/video_frame.cc \
+ $${PPAPI_CPP_SOURCE}/websocket.cc
+
# libppapi (stub)
SOURCES += \
@@ -65,8 +71,32 @@ SOURCES += \
# rest of libppapi is implemented in JavasScript and added to the build
# with '--pre-js' at link time.
+!emscripten {
+# Emscripten provides a better GLES2 API directly than pepper.js
+# TODO Consider adding back this when pepper.js has better GLES2 support
# OpenGL
PPAPI_GLES_SOURCE= $$(NACL_SDK_ROOT)/src/ppapi_gles2
SOURCES +=\
$${PPAPI_GLES_SOURCE}/gles2.c \
$${PPAPI_GLES_SOURCE}/gl2ext_ppapi.c \
+
+}
+
+OTHER_FILES += \
+ $$PWD/3rdparty/pepper.js/audio.js \
+ $$PWD/3rdparty/pepper.js/base.js \
+ $$PWD/3rdparty/pepper.js/common.js \
+ $$PWD/3rdparty/pepper.js/file.js \
+ $$PWD/3rdparty/pepper.js/gles.js \
+ $$PWD/3rdparty/pepper.js/gles_ext.js \
+ $$PWD/3rdparty/pepper.js/graphics_2d.js \
+ $$PWD/3rdparty/pepper.js/graphics_3d.js \
+ $$PWD/3rdparty/pepper.js/input_events.js \
+ $$PWD/3rdparty/pepper.js/loadnacl.js \
+ $$PWD/3rdparty/pepper.js/mouse_lock.js \
+ $$PWD/3rdparty/pepper.js/ppapi_preamble.js \
+ $$PWD/3rdparty/pepper.js/testing.js \
+ $$PWD/3rdparty/pepper.js/url_loader.js \
+ $$PWD/3rdparty/pepper.js/view.js \
+ $$PWD/3rdparty/pepper.js/web_socket.js \
+ $$PWD/3rdparty/pepper.js/LICENSE
diff --git a/src/plugins/platforms/pepper/qpeppereventdispatcher.cpp b/src/plugins/platforms/pepper/qpeppereventdispatcher.cpp
index c5549c75f7..7af6b2d161 100644
--- a/src/plugins/platforms/pepper/qpeppereventdispatcher.cpp
+++ b/src/plugins/platforms/pepper/qpeppereventdispatcher.cpp
@@ -45,6 +45,7 @@ QPepperEventDispatcher::QPepperEventDispatcher(QObject *parent)
, m_currentTimerSerial(0)
, m_messageLoop(pp::MessageLoop::GetCurrent())
, m_completionCallbackFactory(this)
+ , m_hasPendingProcessEvents(false)
{
qCDebug(QT_PLATFORM_PEPPER_EVENTDISPATHCER) << "QPepperEventDispatcher()";
}
@@ -54,9 +55,25 @@ QPepperEventDispatcher::~QPepperEventDispatcher() {}
bool QPepperEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
{
bool processed = false;
+#ifdef Q_OS_NACL_EMSCRIPTEN
+ // We need to give the control back to the browser due to lack of PTHREADS
+ // Limit the number of events that may be processed at the time
+ // TODO: Set maxProcessedEvents to the actual number of pending events, the real issue is that events may spawn new events
+ int maxProcessedEvents = 2;
+ int processedCount = 0;
+ do {
+ processed = QUnixEventDispatcherQPA::processEvents(flags);
+ processedCount += 1;
+ } while (processed && hasPendingEvents() && processedCount < maxProcessedEvents);
+ // Schedule a new processing loop if we still have events pending
+ if (hasPendingEvents()) {
+ scheduleProcessEvents();
+ }
+#else
do {
processed = QUnixEventDispatcherQPA::processEvents(flags);
} while (processed && hasPendingEvents());
+#endif
return true;
}
@@ -193,19 +210,23 @@ void QPepperEventDispatcher::timerCallback(int32_t result, int32_t timerSerial)
void QPepperEventDispatcher::scheduleProcessEvents()
{
- qCDebug(QT_PLATFORM_PEPPER_EVENTDISPATHCER) << "scheduleProcessEvents";
- pp::CompletionCallback processEvents
- = m_completionCallbackFactory.NewCallback(&QPepperEventDispatcher::processEventsCallback);
- int32_t result = m_messageLoop.PostWork(processEvents);
- if (result != PP_OK)
- qCDebug(QT_PLATFORM_PEPPER_EVENTDISPATHCER) << "scheduleProcessEvents PostWork error"
- << result;
+ qCDebug(QT_PLATFORM_PEPPER_EVENTDISPATHCER) << "scheduleProcessEvents" << m_hasPendingProcessEvents;
+ if (!m_hasPendingProcessEvents) {
+ m_hasPendingProcessEvents = true;
+ pp::CompletionCallback processEvents
+ = m_completionCallbackFactory.NewCallback(&QPepperEventDispatcher::processEventsCallback);
+ int32_t result = m_messageLoop.PostWork(processEvents);
+ if (result != PP_OK)
+ qCDebug(QT_PLATFORM_PEPPER_EVENTDISPATHCER) << "scheduleProcessEvents PostWork error"
+ << result;
+ }
}
void QPepperEventDispatcher::processEventsCallback(int32_t status)
{
Q_UNUSED(status);
qCDebug(QT_PLATFORM_PEPPER_EVENTDISPATHCER) << "processEvents";
+ m_hasPendingProcessEvents = false;
processEvents();
}
diff --git a/src/plugins/platforms/pepper/qpeppereventdispatcher.h b/src/plugins/platforms/pepper/qpeppereventdispatcher.h
index 935f8ac653..efcb458b11 100644
--- a/src/plugins/platforms/pepper/qpeppereventdispatcher.h
+++ b/src/plugins/platforms/pepper/qpeppereventdispatcher.h
@@ -94,6 +94,7 @@ private:
QHash<int, PepperTimerInfo> m_timerDetails;
pp::MessageLoop m_messageLoop;
pp::CompletionCallbackFactory<QPepperEventDispatcher> m_completionCallbackFactory;
+ bool m_hasPendingProcessEvents;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/pepper/qpepperfontdatabase.cpp b/src/plugins/platforms/pepper/qpepperfontdatabase.cpp
index e542939587..5b816b8059 100644
--- a/src/plugins/platforms/pepper/qpepperfontdatabase.cpp
+++ b/src/plugins/platforms/pepper/qpepperfontdatabase.cpp
@@ -49,6 +49,8 @@ void QPepperFontDatabase::populateFontDatabase()
registerFont("Arial", "", QFont::Normal, QFont::StyleNormal, QFont::Unstretched, true, true, 12,
writingSystems, 0);
#else
+ Q_INIT_RESOURCE(naclfonts);
+
// Load font file from resources. Currently
// all fonts needs to be bundled with the nexe
// as Qt resources.
diff --git a/src/plugins/platforms/pepper/qpepperglcontext.cpp b/src/plugins/platforms/pepper/qpepperglcontext.cpp
index 7587062c05..da7cc315fd 100644
--- a/src/plugins/platforms/pepper/qpepperglcontext.cpp
+++ b/src/plugins/platforms/pepper/qpepperglcontext.cpp
@@ -44,7 +44,12 @@
#include <ppapi/cpp/graphics_3d.h>
#include <ppapi/cpp/graphics_3d_client.h>
+
+// Emscriptens GLES2 API is more complete than pepper.js
+#ifndef Q_OS_NACL_EMSCRIPTEN
#include <ppapi/gles2/gl2ext_ppapi.h>
+#endif
+
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
@@ -109,15 +114,18 @@ bool QPepperGLContext::makeCurrent(QPlatformSurface *surface)
}
m_currentSize = newSize;
}
-
+#ifndef Q_OS_NACL_EMSCRIPTEN
glSetCurrentContextPPAPI(m_context.pp_resource());
+#endif
return true;
}
void QPepperGLContext::doneCurrent()
{
qCDebug(QT_PLATFORM_PEPPER_GLCONTEXT) << "doneCurrent";
+#ifndef Q_OS_NACL_EMSCRIPTEN
glSetCurrentContextPPAPI(0);
+#endif
}
QFunctionPointer QPepperGLContext::getProcAddress(const QByteArray &procName)
@@ -144,10 +152,12 @@ void QPepperGLContext::flushCallback(int32_t)
bool QPepperGLContext::initGl()
{
qCDebug(QT_PLATFORM_PEPPER_GLCONTEXT) << "initGl";
+#ifndef Q_OS_NACL_EMSCRIPTEN
if (!glInitializePPAPI(pp::Module::Get()->get_browser_interface())) {
qWarning("Unable to initialize GL PPAPI!\n");
return false;
}
+#endif
m_currentSize = QPepperInstancePrivate::get()->geometry().size();
QSurfaceFormat f = format();
@@ -165,7 +175,9 @@ bool QPepperGLContext::initGl()
if (!instance->BindGraphics(m_context)) {
qWarning("Unable to bind 3d context!\n");
m_context = pp::Graphics3D();
+#ifndef Q_OS_NACL_EMSCRIPTEN
glSetCurrentContextPPAPI(0);
+#endif
return false;
}
diff --git a/src/plugins/platforms/pepper/qpepperpluginmain.cpp b/src/plugins/platforms/pepper/qpepperpluginmain.cpp
index 598401e57f..dfc7545626 100644
--- a/src/plugins/platforms/pepper/qpepperpluginmain.cpp
+++ b/src/plugins/platforms/pepper/qpepperpluginmain.cpp
@@ -33,40 +33,43 @@
**
****************************************************************************/
-#include "qpepperintegration.h"
+// TODO: Check if this is needed. Removed because it caused duplicate
+// symbol definition of qt_plugin_query_metadata for everything linking QtGui
-#include <QtCore/QDebug>
-#include <qpa/qplatformintegrationplugin.h>
-
-QT_BEGIN_NAMESPACE
-
-class QPepperIntegrationPlugin : public QPlatformIntegrationPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE
- "pepper.json")
-public:
- QStringList keys() const;
- QPlatformIntegration *create(const QString &, const QStringList &) Q_DECL_OVERRIDE;
-};
-
-QStringList QPepperIntegrationPlugin::keys() const
-{
- QStringList list;
- list << QStringLiteral("pepper");
- return list;
-}
-
-QPlatformIntegration *QPepperIntegrationPlugin::create(const QString &system,
- const QStringList &paramList)
-{
- Q_UNUSED(paramList);
- // qDebug() << "QPepperIntegrationPlugin::create" << system;
- if (system.toLower() == QStringLiteral("pepper"))
- return new QPepperIntegration;
- return 0;
-}
-
-QT_END_NAMESPACE
-
-#include "qpepperpluginmain.moc"
+// #include "qpepperintegration.h"
+//
+// #include <QtCore/QDebug>
+// #include <qpa/qplatformintegrationplugin.h>
+//
+// QT_BEGIN_NAMESPACE
+//
+// class QPepperIntegrationPlugin : public QPlatformIntegrationPlugin
+// {
+// Q_OBJECT
+// Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE
+// "pepper.json")
+// public:
+// QStringList keys() const;
+// QPlatformIntegration *create(const QString &, const QStringList &) Q_DECL_OVERRIDE;
+// };
+//
+// QStringList QPepperIntegrationPlugin::keys() const
+// {
+// QStringList list;
+// list << QStringLiteral("pepper");
+// return list;
+// }
+//
+// QPlatformIntegration *QPepperIntegrationPlugin::create(const QString &system,
+// const QStringList &paramList)
+// {
+// Q_UNUSED(paramList);
+// // qDebug() << "QPepperIntegrationPlugin::create" << system;
+// if (system.toLower() == QStringLiteral("pepper"))
+// return new QPepperIntegration;
+// return 0;
+// }
+//
+// QT_END_NAMESPACE
+//
+// #include "qpepperpluginmain.moc"
diff --git a/src/tools/nacldeployqt/main.cpp b/src/tools/nacldeployqt/main.cpp
index cdc982e8f8..418c5fc4e7 100644
--- a/src/tools/nacldeployqt/main.cpp
+++ b/src/tools/nacldeployqt/main.cpp
@@ -46,7 +46,7 @@ private:
QString findPNaClTool(const QString &sdkRoot, const QString &toolName);
QList<QByteArray> quote(const QList<QByteArray> &list);
void runCommand(const QString &command);
- bool copyRecursively(const QString &srcFilePath, const QString &tgtFilePath);
+ bool copyRecursively(const QString &srcFilePath, const QString &tgtFilePath, bool skipBinaries);
QByteArray instantiateTemplate(const QByteArray &tmplate);
void instantiateWriteTemplate(const QByteArray &tmplate, const QString &filePath);
};
@@ -172,7 +172,11 @@ int QtNaclDeployer::deploy()
QString target = targetBase + "/" + import;
// TODO: Skip the binaries for static builds; they will be built into the main nexe
- copyRecursively(source, target);
+ bool skipBinaries = false;
+ if (deploymentType == Emscripten) {
+ skipBinaries = true;
+ }
+ copyRecursively(source, target, skipBinaries);
}
}
@@ -390,7 +394,8 @@ void QtNaclDeployer::runCommand(const QString &command)
}
bool QtNaclDeployer::copyRecursively(const QString &srcFilePath,
- const QString &tgtFilePath)
+ const QString &tgtFilePath,
+ bool skipBinaries)
{
QFileInfo srcFileInfo(srcFilePath);
if (srcFileInfo.isDir()) {
@@ -402,11 +407,14 @@ bool QtNaclDeployer::copyRecursively(const QString &srcFilePath,
QDir sourceDir(srcFilePath);
QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
foreach (const QString &fileName, fileNames) {
+ if (skipBinaries && (fileName.endsWith(".so") || fileName.endsWith(".a"))) {
+ continue;
+ }
const QString newSrcFilePath
= srcFilePath + QLatin1Char('/') + fileName;
const QString newTgtFilePath
= tgtFilePath + QLatin1Char('/') + fileName;
- if (!copyRecursively(newSrcFilePath, newTgtFilePath))
+ if (!copyRecursively(newSrcFilePath, newTgtFilePath, skipBinaries))
return false;
}
} else {
diff --git a/src/tools/nacldeployqt/template_qtloader.cpp b/src/tools/nacldeployqt/template_qtloader.cpp
index fdf3d313ad..201e387066 100644
--- a/src/tools/nacldeployqt/template_qtloader.cpp
+++ b/src/tools/nacldeployqt/template_qtloader.cpp
@@ -2,7 +2,7 @@ const char *templateQtLoader = R"STRING_DELIMITER(
// This script is generated by nacldeployqt as a part of the standard
// Qt deployment. It can be used either as-is or as a basis for a
// custom deployment solution. Note that some parts of this script
-// (such as onMessage) is required by Qt.
+// (such as onMessage) are required by Qt.
//
// Usage:
//
@@ -49,6 +49,10 @@ const char *templateQtLoader = R"STRING_DELIMITER(
// 1) As argn, argv key/value pairs to Init() of a QPepperInstance subclass.
// 2) As environment variables: toUpper(key)=value.
+var doCreateInstance = function () {
+ console.log("Please call QtLoader.load() instead of loading your application script.")
+}
+
function QtLoader(config) {
var self = this;
self.config = config;
@@ -182,14 +186,6 @@ function onLoad(event)
self.embed.style.visibility = "visible"
}
-function loadScript(src, onload)
-{
- var script = document.createElement('script')
- script.src = src
- script.onload = function () { onload() };
- document.head.appendChild(script);
-}
-
// Create Qt container element, possibly re-using existingElement
function createElement(existingElement)
{
@@ -263,15 +259,20 @@ function loadEmscripten()
var height = self.listener.offsetHeight
var embed = document.createElement("div");
+ self.embed = embed
embed.setAttribute("class", "qt-embed");
self.listener.appendChild(embed);
self.listener.embed = embed;
- loadScript(config.src, function(){
+ doCreateInstance = function() {
CreateInstance(width, height, embed);
embed.finishLoading();
- })
-}
+ };
+
+ var script = document.createElement('script')
+ script.src = config.src;
+ document.head.appendChild(script);
+};
function postMessage(message) {
self.embed.postMessage(message)