Remove last traces of MeeGo
Change-Id: I5242f1dfcfccf9811398e717b90196e6228d1dc5 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
This commit is contained in:
parent
f17605777b
commit
04b276b0f5
@ -24,7 +24,6 @@ qtConfig(opengl) {
|
|||||||
opengl/qopenglcustomshaderstage_p.h \
|
opengl/qopenglcustomshaderstage_p.h \
|
||||||
opengl/qopengltextureglyphcache_p.h \
|
opengl/qopengltextureglyphcache_p.h \
|
||||||
opengl/qopenglshadercache_p.h \
|
opengl/qopenglshadercache_p.h \
|
||||||
opengl/qopenglshadercache_meego_p.h \
|
|
||||||
opengl/qopenglversionfunctions.h \
|
opengl/qopenglversionfunctions.h \
|
||||||
opengl/qopenglversionfunctionsfactory_p.h \
|
opengl/qopenglversionfunctionsfactory_p.h \
|
||||||
opengl/qopenglvertexarrayobject.h \
|
opengl/qopenglvertexarrayobject.h \
|
||||||
|
@ -1,450 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of the QtGui module of the Qt Toolkit.
|
|
||||||
**
|
|
||||||
** $QT_BEGIN_LICENSE:LGPL$
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms
|
|
||||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
||||||
** information use the contact form at https://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
||||||
** General Public License version 3 as published by the Free Software
|
|
||||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
|
||||||
** packaging of this file. Please review the following information to
|
|
||||||
** ensure the GNU Lesser General Public License version 3 requirements
|
|
||||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU
|
|
||||||
** General Public License version 2.0 or (at your option) the GNU General
|
|
||||||
** Public license version 3 or any later version approved by the KDE Free
|
|
||||||
** Qt Foundation. The licenses are as published by the Free Software
|
|
||||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
|
||||||
** included in the packaging of this file. Please review the following
|
|
||||||
** information to ensure the GNU General Public License requirements will
|
|
||||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
|
||||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
|
||||||
**
|
|
||||||
** $QT_END_LICENSE$
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
//
|
|
||||||
// W A R N I N G
|
|
||||||
// -------------
|
|
||||||
//
|
|
||||||
// This file is not part of the Qt API. It exists purely as an
|
|
||||||
// implementation detail. This header file may change from version to
|
|
||||||
// version without notice, or even be removed.
|
|
||||||
//
|
|
||||||
// We mean it.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef QOPENGLSHADERCACHE_MEEGO_P_H
|
|
||||||
#define QOPENGLSHADERCACHE_MEEGO_P_H
|
|
||||||
|
|
||||||
#include <QtCore/qopenglobal.h>
|
|
||||||
|
|
||||||
#if defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE) && defined(QT_OPENGL_ES_2)
|
|
||||||
|
|
||||||
#include <QtCore/qcryptographichash.h>
|
|
||||||
#include <QtCore/qsharedmemory.h>
|
|
||||||
#include <QtCore/qsystemsemaphore.h>
|
|
||||||
|
|
||||||
#ifndef QT_BOOTSTRAPPED
|
|
||||||
# include <GLES2/gl2ext.h>
|
|
||||||
#endif
|
|
||||||
#if defined(QT_DEBUG) || defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE_TRACE)
|
|
||||||
# include <syslog.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
This cache stores internal Qt shader programs in shared memory.
|
|
||||||
|
|
||||||
This header file is ugly on purpose and can only be included once. It is only to be used
|
|
||||||
for the internal shader cache, not as a generic cache for anyone's shaders.
|
|
||||||
|
|
||||||
The cache stores either ShaderCacheMaxEntries shader programs or ShaderCacheDataSize kilobytes
|
|
||||||
of shader programs, whatever limit is reached first.
|
|
||||||
|
|
||||||
The layout of the cache is as outlined in the CachedShaders struct. After some
|
|
||||||
integers, an array of headers is reserved, then comes the space for the actual binaries.
|
|
||||||
|
|
||||||
Shader Programs are identified by the md5sum of their frag and vertex shader source code.
|
|
||||||
|
|
||||||
Shader Programs are never removed. The cache never shrinks or re-shuffles. This is done
|
|
||||||
on purpose to ensure minimum amount of locking, no alignment problems and very few write
|
|
||||||
operations.
|
|
||||||
|
|
||||||
Note: Locking the shader cache could be expensive, because the entire system might hang.
|
|
||||||
That's why the cache is immutable to minimize the time we need to keep it locked.
|
|
||||||
|
|
||||||
Why is it Meego specific?
|
|
||||||
|
|
||||||
First, the size is chosen so that it fits to generic meego usage. Second, on Meego, there's
|
|
||||||
always at least one Qt application active (the launcher), so the cache will never be destroyed.
|
|
||||||
Only when the last Qt app exits, the cache dies, which should only be when someone kills the
|
|
||||||
X11 server. And last but not least it was only tested with Meego's SGX driver.
|
|
||||||
|
|
||||||
There's a small tool in src/opengl/util/meego that dumps the contents of the cache.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// anonymous namespace, prevent exporting of the private symbols
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
struct CachedShaderHeader
|
|
||||||
{
|
|
||||||
/* the index in the data[] member of CachedShaders */
|
|
||||||
int index;
|
|
||||||
/* the size of the binary shader */
|
|
||||||
GLsizei size;
|
|
||||||
/* the format of the binary shader */
|
|
||||||
GLenum format;
|
|
||||||
/* the md5sum of the frag+vertex shaders */
|
|
||||||
char md5Sum[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
/* The maximum amount of shader programs the cache can hold */
|
|
||||||
ShaderCacheMaxEntries = 20
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef CachedShaderHeader CachedShaderHeaders[ShaderCacheMaxEntries];
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
// ShaderCacheDataSize is 20k minus the other data members of CachedShaders
|
|
||||||
ShaderCacheDataSize = 1024 * ShaderCacheMaxEntries - sizeof(CachedShaderHeaders) - 2 * sizeof(int)
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CachedShaders
|
|
||||||
{
|
|
||||||
/* How much space is still available in the cache */
|
|
||||||
inline int availableSize() const { return ShaderCacheDataSize - dataSize; }
|
|
||||||
|
|
||||||
/* The current amount of cached shaders */
|
|
||||||
int shaderCount;
|
|
||||||
|
|
||||||
/* The current amount (in bytes) of cached data */
|
|
||||||
int dataSize;
|
|
||||||
|
|
||||||
/* The headers describing the shaders */
|
|
||||||
CachedShaderHeaders headers;
|
|
||||||
|
|
||||||
/* The actual binary data of the shader programs */
|
|
||||||
char data[ShaderCacheDataSize];
|
|
||||||
};
|
|
||||||
|
|
||||||
//#define QT_DEBUG_SHADER_CACHE
|
|
||||||
#ifdef QT_DEBUG_SHADER_CACHE
|
|
||||||
static QDebug shaderCacheDebug()
|
|
||||||
{
|
|
||||||
return QDebug(QtDebugMsg);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline QNoDebug shaderCacheDebug() { return QNoDebug(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class ShaderCacheSharedMemory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ShaderCacheSharedMemory()
|
|
||||||
: shm(QLatin1String("qt_gles2_shadercache_" QT_VERSION_STR))
|
|
||||||
{
|
|
||||||
// we need a system semaphore here, since cache creation and initialization must be atomic
|
|
||||||
QSystemSemaphore attachSemaphore(QLatin1String("qt_gles2_shadercache_mutex_" QT_VERSION_STR), 1);
|
|
||||||
|
|
||||||
if (!attachSemaphore.acquire()) {
|
|
||||||
shaderCacheDebug() << "Unable to require shader cache semaphore:" << attachSemaphore.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shm.attach()) {
|
|
||||||
// success!
|
|
||||||
shaderCacheDebug() << "Attached to shader cache";
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// no cache exists - create and initialize it
|
|
||||||
if (shm.create(sizeof(CachedShaders))) {
|
|
||||||
shaderCacheDebug() << "Created new shader cache";
|
|
||||||
initializeCache();
|
|
||||||
} else {
|
|
||||||
shaderCacheDebug() << "Unable to create shader cache:" << shm.errorString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attachSemaphore.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isAttached() const { return shm.isAttached(); }
|
|
||||||
|
|
||||||
inline bool lock() { return shm.lock(); }
|
|
||||||
inline bool unlock() { return shm.unlock(); }
|
|
||||||
inline void *data() { return shm.data(); }
|
|
||||||
inline QString errorString() { return shm.errorString(); }
|
|
||||||
|
|
||||||
~ShaderCacheSharedMemory()
|
|
||||||
{
|
|
||||||
if (!shm.detach())
|
|
||||||
shaderCacheDebug() << "Unable to detach shader cache" << shm.errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initializeCache()
|
|
||||||
{
|
|
||||||
// no need to lock the shared memory since we're already protected by the
|
|
||||||
// attach system semaphore.
|
|
||||||
|
|
||||||
void *data = shm.data();
|
|
||||||
Q_ASSERT(data);
|
|
||||||
|
|
||||||
memset(data, 0, sizeof(CachedShaders));
|
|
||||||
}
|
|
||||||
|
|
||||||
QSharedMemory shm;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShaderCacheLocker
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline ShaderCacheLocker(ShaderCacheSharedMemory *cache)
|
|
||||||
: shm(cache->lock() ? cache : (ShaderCacheSharedMemory *)0)
|
|
||||||
{
|
|
||||||
if (!shm)
|
|
||||||
shaderCacheDebug() << "Unable to lock shader cache" << cache->errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isLocked() const { return shm; }
|
|
||||||
|
|
||||||
inline ~ShaderCacheLocker()
|
|
||||||
{
|
|
||||||
if (!shm)
|
|
||||||
return;
|
|
||||||
if (!shm->unlock())
|
|
||||||
shaderCacheDebug() << "Unable to unlock shader cache" << shm->errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ShaderCacheSharedMemory *shm;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef QT_BOOTSTRAPPED
|
|
||||||
} // end namespace
|
|
||||||
#else
|
|
||||||
|
|
||||||
static void traceCacheOverflow(const char *message)
|
|
||||||
{
|
|
||||||
#if defined(QT_DEBUG) || defined (QT_MEEGO_EXPERIMENTAL_SHADERCACHE_TRACE)
|
|
||||||
openlog(qPrintable(QCoreApplication::applicationName()), LOG_PID | LOG_ODELAY, LOG_USER);
|
|
||||||
syslog(LOG_DEBUG, message);
|
|
||||||
closelog();
|
|
||||||
#endif
|
|
||||||
shaderCacheDebug() << message;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(ShaderCacheSharedMemory, shaderCacheSharedMemory)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Finds the index of the shader program identified by md5Sum in the cache.
|
|
||||||
Note: Does NOT lock the cache for reading, the cache must already be locked!
|
|
||||||
|
|
||||||
Returns -1 when no shader was found.
|
|
||||||
*/
|
|
||||||
static int qt_cache_index_unlocked(const QByteArray &md5Sum, CachedShaders *cache)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < cache->shaderCount; ++i) {
|
|
||||||
if (qstrncmp(md5Sum.constData(), cache->headers[i].md5Sum, 16) == 0) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the index of the shader identified by md5Sum */
|
|
||||||
static int qt_cache_index(const QByteArray &md5Sum)
|
|
||||||
{
|
|
||||||
ShaderCacheSharedMemory *shm = shaderCacheSharedMemory();
|
|
||||||
if (!shm || !shm->isAttached())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Q_ASSERT(md5Sum.length() == 16);
|
|
||||||
|
|
||||||
ShaderCacheLocker locker(shm);
|
|
||||||
if (!locker.isLocked())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
void *data = shm->data();
|
|
||||||
Q_ASSERT(data);
|
|
||||||
|
|
||||||
CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
|
|
||||||
|
|
||||||
return qt_cache_index_unlocked(md5Sum, cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loads the cached shader at index \a shaderIndex into \a program
|
|
||||||
* Note: Since the cache is immutable, this operation doesn't lock the shared memory.
|
|
||||||
*/
|
|
||||||
static bool qt_cached_shader(QOpenGLShaderProgram *program, QOpenGLContext *ctx, int shaderIndex)
|
|
||||||
{
|
|
||||||
Q_ASSERT(shaderIndex >= 0 && shaderIndex <= ShaderCacheMaxEntries);
|
|
||||||
Q_ASSERT(program);
|
|
||||||
|
|
||||||
ShaderCacheSharedMemory *shm = shaderCacheSharedMemory();
|
|
||||||
if (!shm || !shm->isAttached())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
void *data = shm->data();
|
|
||||||
Q_ASSERT(data);
|
|
||||||
|
|
||||||
CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
|
|
||||||
|
|
||||||
shaderCacheDebug() << "fetching cached shader at index" << shaderIndex
|
|
||||||
<< "dataIndex" << cache->headers[shaderIndex].index
|
|
||||||
<< "size" << cache->headers[shaderIndex].size
|
|
||||||
<< "format" << cache->headers[shaderIndex].format;
|
|
||||||
|
|
||||||
// call program->programId first, since that resolves the glProgramBinaryOES symbol
|
|
||||||
GLuint programId = program->programId();
|
|
||||||
glProgramBinaryOES(programId, cache->headers[shaderIndex].format,
|
|
||||||
cache->data + cache->headers[shaderIndex].index,
|
|
||||||
cache->headers[shaderIndex].size);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stores the shader program in the cache. Returns false if there's an error with the cache, or
|
|
||||||
if the cache is too small to hold the shader. */
|
|
||||||
static bool qt_cache_shader(const QOpenGLShaderProgram *shader, QOpenGLContext *ctx, const QByteArray &md5Sum)
|
|
||||||
{
|
|
||||||
ShaderCacheSharedMemory *shm = shaderCacheSharedMemory();
|
|
||||||
if (!shm || !shm->isAttached())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
void *data = shm->data();
|
|
||||||
Q_ASSERT(data);
|
|
||||||
|
|
||||||
CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
|
|
||||||
|
|
||||||
ShaderCacheLocker locker(shm);
|
|
||||||
if (!locker.isLocked())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int cacheIdx = cache->shaderCount;
|
|
||||||
if (cacheIdx >= ShaderCacheMaxEntries) {
|
|
||||||
traceCacheOverflow("Qt OpenGL shader cache index overflow!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now that we have the lock on the shared memory, make sure no one
|
|
||||||
// inserted the shader already while we were unlocked
|
|
||||||
if (qt_cache_index_unlocked(md5Sum, cache) != -1)
|
|
||||||
return true; // already cached
|
|
||||||
|
|
||||||
shaderCacheDebug() << "Caching shader at index" << cacheIdx;
|
|
||||||
|
|
||||||
GLint binaryLength = 0;
|
|
||||||
glGetProgramiv(shader->programId(), GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength);
|
|
||||||
|
|
||||||
if (!binaryLength) {
|
|
||||||
shaderCacheDebug() << "Unable to determine binary shader size!";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binaryLength > cache->availableSize()) {
|
|
||||||
traceCacheOverflow("Qt OpenGL shader cache data overflow!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLsizei size = 0;
|
|
||||||
GLenum format = 0;
|
|
||||||
glGetProgramBinaryOES(shader->programId(), binaryLength, &size, &format,
|
|
||||||
cache->data + cache->dataSize);
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
shaderCacheDebug() << "Unable to get binary shader!";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cache->headers[cacheIdx].index = cache->dataSize;
|
|
||||||
cache->dataSize += binaryLength;
|
|
||||||
++cache->shaderCount;
|
|
||||||
cache->headers[cacheIdx].size = binaryLength;
|
|
||||||
cache->headers[cacheIdx].format = format;
|
|
||||||
|
|
||||||
memcpy(cache->headers[cacheIdx].md5Sum, md5Sum.constData(), 16);
|
|
||||||
|
|
||||||
shaderCacheDebug() << "cached shader size" << size
|
|
||||||
<< "format" << format
|
|
||||||
<< "binarySize" << binaryLength
|
|
||||||
<< "cache index" << cacheIdx
|
|
||||||
<< "data index" << cache->headers[cacheIdx].index;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
|
|
||||||
class CachedShader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CachedShader(const QByteArray &fragSource, const QByteArray &vertexSource)
|
|
||||||
: cacheIdx(-1)
|
|
||||||
{
|
|
||||||
QCryptographicHash md5Hash(QCryptographicHash::Md5);
|
|
||||||
|
|
||||||
md5Hash.addData(fragSource);
|
|
||||||
md5Hash.addData(vertexSource);
|
|
||||||
|
|
||||||
md5Sum = md5Hash.result();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isCached()
|
|
||||||
{
|
|
||||||
return cacheIndex() != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cacheIndex()
|
|
||||||
{
|
|
||||||
if (cacheIdx != -1)
|
|
||||||
return cacheIdx;
|
|
||||||
cacheIdx = qt_cache_index(md5Sum);
|
|
||||||
return cacheIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool load(QOpenGLShaderProgram *program, QOpenGLContext *ctx)
|
|
||||||
{
|
|
||||||
if (cacheIndex() == -1)
|
|
||||||
return false;
|
|
||||||
return qt_cached_shader(program, ctx, cacheIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool store(QOpenGLShaderProgram *program, QOpenGLContext *ctx)
|
|
||||||
{
|
|
||||||
return qt_cache_shader(program, ctx, md5Sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QByteArray md5Sum;
|
|
||||||
int cacheIdx;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -53,10 +53,6 @@
|
|||||||
|
|
||||||
#include <QtGui/private/qtguiglobal_p.h>
|
#include <QtGui/private/qtguiglobal_p.h>
|
||||||
|
|
||||||
#if defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE) && defined(QT_OPENGL_ES_2)
|
|
||||||
# include "qopenglshadercache_meego_p.h"
|
|
||||||
#else
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
@ -88,4 +84,3 @@ public:
|
|||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
@ -2643,7 +2643,7 @@ bool QSslSocketPrivate::rootCertOnDemandLoadingSupported()
|
|||||||
*/
|
*/
|
||||||
QList<QByteArray> QSslSocketPrivate::unixRootCertDirectories()
|
QList<QByteArray> QSslSocketPrivate::unixRootCertDirectories()
|
||||||
{
|
{
|
||||||
return QList<QByteArray>() << "/etc/ssl/certs/" // (K)ubuntu, OpenSUSE, Mandriva, MeeGo ...
|
return QList<QByteArray>() << "/etc/ssl/certs/" // (K)ubuntu, OpenSUSE, Mandriva ...
|
||||||
<< "/usr/lib/ssl/certs/" // Gentoo, Mandrake
|
<< "/usr/lib/ssl/certs/" // Gentoo, Mandrake
|
||||||
<< "/usr/share/ssl/" // Centos, Redhat, SuSE
|
<< "/usr/share/ssl/" // Centos, Redhat, SuSE
|
||||||
<< "/usr/local/ssl/" // Normal OpenSSL Tarball
|
<< "/usr/local/ssl/" // Normal OpenSSL Tarball
|
||||||
|
@ -1,450 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
**
|
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
|
||||||
** Contact: https://www.qt.io/licensing/
|
|
||||||
**
|
|
||||||
** This file is part of the QtOpenGL module of the Qt Toolkit.
|
|
||||||
**
|
|
||||||
** $QT_BEGIN_LICENSE:LGPL$
|
|
||||||
** Commercial License Usage
|
|
||||||
** Licensees holding valid commercial Qt licenses may use this file in
|
|
||||||
** accordance with the commercial license agreement provided with the
|
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
|
||||||
** a written agreement between you and The Qt Company. For licensing terms
|
|
||||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
||||||
** information use the contact form at https://www.qt.io/contact-us.
|
|
||||||
**
|
|
||||||
** GNU Lesser General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
||||||
** General Public License version 3 as published by the Free Software
|
|
||||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
|
||||||
** packaging of this file. Please review the following information to
|
|
||||||
** ensure the GNU Lesser General Public License version 3 requirements
|
|
||||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
|
||||||
**
|
|
||||||
** GNU General Public License Usage
|
|
||||||
** Alternatively, this file may be used under the terms of the GNU
|
|
||||||
** General Public License version 2.0 or (at your option) the GNU General
|
|
||||||
** Public license version 3 or any later version approved by the KDE Free
|
|
||||||
** Qt Foundation. The licenses are as published by the Free Software
|
|
||||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
|
||||||
** included in the packaging of this file. Please review the following
|
|
||||||
** information to ensure the GNU General Public License requirements will
|
|
||||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
|
||||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
|
||||||
**
|
|
||||||
** $QT_END_LICENSE$
|
|
||||||
**
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
//
|
|
||||||
// W A R N I N G
|
|
||||||
// -------------
|
|
||||||
//
|
|
||||||
// This file is not part of the Qt API. It exists purely as an
|
|
||||||
// implementation detail. This header file may change from version to
|
|
||||||
// version without notice, or even be removed.
|
|
||||||
//
|
|
||||||
// We mean it.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef QGLSHADERCACHE_MEEGO_P_H
|
|
||||||
#define QGLSHADERCACHE_MEEGO_P_H
|
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
|
||||||
|
|
||||||
#if defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE) && defined(QT_OPENGL_ES_2)
|
|
||||||
|
|
||||||
#include <QtCore/qcryptographichash.h>
|
|
||||||
#include <QtCore/qsharedmemory.h>
|
|
||||||
#include <QtCore/qsystemsemaphore.h>
|
|
||||||
|
|
||||||
#ifndef QT_BOOTSTRAPPED
|
|
||||||
# include <GLES2/gl2ext.h>
|
|
||||||
#endif
|
|
||||||
#if defined(QT_DEBUG) || defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE_TRACE)
|
|
||||||
# include <syslog.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
This cache stores internal Qt shader programs in shared memory.
|
|
||||||
|
|
||||||
This header file is ugly on purpose and can only be included once. It is only to be used
|
|
||||||
for the internal shader cache, not as a generic cache for anyone's shaders.
|
|
||||||
|
|
||||||
The cache stores either ShaderCacheMaxEntries shader programs or ShaderCacheDataSize kilobytes
|
|
||||||
of shader programs, whatever limit is reached first.
|
|
||||||
|
|
||||||
The layout of the cache is as outlined in the CachedShaders struct. After some
|
|
||||||
integers, an array of headers is reserved, then comes the space for the actual binaries.
|
|
||||||
|
|
||||||
Shader Programs are identified by the md5sum of their frag and vertex shader source code.
|
|
||||||
|
|
||||||
Shader Programs are never removed. The cache never shrinks or re-shuffles. This is done
|
|
||||||
on purpose to ensure minimum amount of locking, no alignment problems and very few write
|
|
||||||
operations.
|
|
||||||
|
|
||||||
Note: Locking the shader cache could be expensive, because the entire system might hang.
|
|
||||||
That's why the cache is immutable to minimize the time we need to keep it locked.
|
|
||||||
|
|
||||||
Why is it Meego specific?
|
|
||||||
|
|
||||||
First, the size is chosen so that it fits to generic meego usage. Second, on Meego, there's
|
|
||||||
always at least one Qt application active (the launcher), so the cache will never be destroyed.
|
|
||||||
Only when the last Qt app exits, the cache dies, which should only be when someone kills the
|
|
||||||
X11 server. And last but not least it was only tested with Meego's SGX driver.
|
|
||||||
|
|
||||||
There's a small tool in src/opengl/util/meego that dumps the contents of the cache.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// anonymous namespace, prevent exporting of the private symbols
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
struct CachedShaderHeader
|
|
||||||
{
|
|
||||||
/* the index in the data[] member of CachedShaders */
|
|
||||||
int index;
|
|
||||||
/* the size of the binary shader */
|
|
||||||
GLsizei size;
|
|
||||||
/* the format of the binary shader */
|
|
||||||
GLenum format;
|
|
||||||
/* the md5sum of the frag+vertex shaders */
|
|
||||||
char md5Sum[16];
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
/* The maximum amount of shader programs the cache can hold */
|
|
||||||
ShaderCacheMaxEntries = 20
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef CachedShaderHeader CachedShaderHeaders[ShaderCacheMaxEntries];
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
// ShaderCacheDataSize is 20k minus the other data members of CachedShaders
|
|
||||||
ShaderCacheDataSize = 1024 * ShaderCacheMaxEntries - sizeof(CachedShaderHeaders) - 2 * sizeof(int)
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CachedShaders
|
|
||||||
{
|
|
||||||
/* How much space is still available in the cache */
|
|
||||||
inline int availableSize() const { return ShaderCacheDataSize - dataSize; }
|
|
||||||
|
|
||||||
/* The current amount of cached shaders */
|
|
||||||
int shaderCount;
|
|
||||||
|
|
||||||
/* The current amount (in bytes) of cached data */
|
|
||||||
int dataSize;
|
|
||||||
|
|
||||||
/* The headers describing the shaders */
|
|
||||||
CachedShaderHeaders headers;
|
|
||||||
|
|
||||||
/* The actual binary data of the shader programs */
|
|
||||||
char data[ShaderCacheDataSize];
|
|
||||||
};
|
|
||||||
|
|
||||||
//#define QT_DEBUG_SHADER_CACHE
|
|
||||||
#ifdef QT_DEBUG_SHADER_CACHE
|
|
||||||
static QDebug shaderCacheDebug()
|
|
||||||
{
|
|
||||||
return QDebug(QtDebugMsg);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline QNoDebug shaderCacheDebug() { return QNoDebug(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class ShaderCacheSharedMemory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ShaderCacheSharedMemory()
|
|
||||||
: shm(QLatin1String("qt_gles2_shadercache_" QT_VERSION_STR))
|
|
||||||
{
|
|
||||||
// we need a system semaphore here, since cache creation and initialization must be atomic
|
|
||||||
QSystemSemaphore attachSemaphore(QLatin1String("qt_gles2_shadercache_mutex_" QT_VERSION_STR), 1);
|
|
||||||
|
|
||||||
if (!attachSemaphore.acquire()) {
|
|
||||||
shaderCacheDebug() << "Unable to require shader cache semaphore:" << attachSemaphore.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shm.attach()) {
|
|
||||||
// success!
|
|
||||||
shaderCacheDebug() << "Attached to shader cache";
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// no cache exists - create and initialize it
|
|
||||||
if (shm.create(sizeof(CachedShaders))) {
|
|
||||||
shaderCacheDebug() << "Created new shader cache";
|
|
||||||
initializeCache();
|
|
||||||
} else {
|
|
||||||
shaderCacheDebug() << "Unable to create shader cache:" << shm.errorString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attachSemaphore.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isAttached() const { return shm.isAttached(); }
|
|
||||||
|
|
||||||
inline bool lock() { return shm.lock(); }
|
|
||||||
inline bool unlock() { return shm.unlock(); }
|
|
||||||
inline void *data() { return shm.data(); }
|
|
||||||
inline QString errorString() { return shm.errorString(); }
|
|
||||||
|
|
||||||
~ShaderCacheSharedMemory()
|
|
||||||
{
|
|
||||||
if (!shm.detach())
|
|
||||||
shaderCacheDebug() << "Unable to detach shader cache" << shm.errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void initializeCache()
|
|
||||||
{
|
|
||||||
// no need to lock the shared memory since we're already protected by the
|
|
||||||
// attach system semaphore.
|
|
||||||
|
|
||||||
void *data = shm.data();
|
|
||||||
Q_ASSERT(data);
|
|
||||||
|
|
||||||
memset(data, 0, sizeof(CachedShaders));
|
|
||||||
}
|
|
||||||
|
|
||||||
QSharedMemory shm;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShaderCacheLocker
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline ShaderCacheLocker(ShaderCacheSharedMemory *cache)
|
|
||||||
: shm(cache->lock() ? cache : (ShaderCacheSharedMemory *)0)
|
|
||||||
{
|
|
||||||
if (!shm)
|
|
||||||
shaderCacheDebug() << "Unable to lock shader cache" << cache->errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isLocked() const { return shm; }
|
|
||||||
|
|
||||||
inline ~ShaderCacheLocker()
|
|
||||||
{
|
|
||||||
if (!shm)
|
|
||||||
return;
|
|
||||||
if (!shm->unlock())
|
|
||||||
shaderCacheDebug() << "Unable to unlock shader cache" << shm->errorString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ShaderCacheSharedMemory *shm;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef QT_BOOTSTRAPPED
|
|
||||||
} // end namespace
|
|
||||||
#else
|
|
||||||
|
|
||||||
static void traceCacheOverflow(const char *message)
|
|
||||||
{
|
|
||||||
#if defined(QT_DEBUG) || defined (QT_MEEGO_EXPERIMENTAL_SHADERCACHE_TRACE)
|
|
||||||
openlog(qPrintable(QCoreApplication::applicationName()), LOG_PID | LOG_ODELAY, LOG_USER);
|
|
||||||
syslog(LOG_DEBUG, message);
|
|
||||||
closelog();
|
|
||||||
#endif
|
|
||||||
shaderCacheDebug() << message;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(ShaderCacheSharedMemory, shaderCacheSharedMemory)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Finds the index of the shader program identified by md5Sum in the cache.
|
|
||||||
Note: Does NOT lock the cache for reading, the cache must already be locked!
|
|
||||||
|
|
||||||
Returns -1 when no shader was found.
|
|
||||||
*/
|
|
||||||
static int qt_cache_index_unlocked(const QByteArray &md5Sum, CachedShaders *cache)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < cache->shaderCount; ++i) {
|
|
||||||
if (qstrncmp(md5Sum.constData(), cache->headers[i].md5Sum, 16) == 0) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns the index of the shader identified by md5Sum */
|
|
||||||
static int qt_cache_index(const QByteArray &md5Sum)
|
|
||||||
{
|
|
||||||
ShaderCacheSharedMemory *shm = shaderCacheSharedMemory();
|
|
||||||
if (!shm || !shm->isAttached())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Q_ASSERT(md5Sum.length() == 16);
|
|
||||||
|
|
||||||
ShaderCacheLocker locker(shm);
|
|
||||||
if (!locker.isLocked())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
void *data = shm->data();
|
|
||||||
Q_ASSERT(data);
|
|
||||||
|
|
||||||
CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
|
|
||||||
|
|
||||||
return qt_cache_index_unlocked(md5Sum, cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loads the cached shader at index \a shaderIndex into \a program
|
|
||||||
* Note: Since the cache is immutable, this operation doesn't lock the shared memory.
|
|
||||||
*/
|
|
||||||
static bool qt_cached_shader(QGLShaderProgram *program, const QGLContext *ctx, int shaderIndex)
|
|
||||||
{
|
|
||||||
Q_ASSERT(shaderIndex >= 0 && shaderIndex <= ShaderCacheMaxEntries);
|
|
||||||
Q_ASSERT(program);
|
|
||||||
|
|
||||||
ShaderCacheSharedMemory *shm = shaderCacheSharedMemory();
|
|
||||||
if (!shm || !shm->isAttached())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
void *data = shm->data();
|
|
||||||
Q_ASSERT(data);
|
|
||||||
|
|
||||||
CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
|
|
||||||
|
|
||||||
shaderCacheDebug() << "fetching cached shader at index" << shaderIndex
|
|
||||||
<< "dataIndex" << cache->headers[shaderIndex].index
|
|
||||||
<< "size" << cache->headers[shaderIndex].size
|
|
||||||
<< "format" << cache->headers[shaderIndex].format;
|
|
||||||
|
|
||||||
// call program->programId first, since that resolves the glProgramBinaryOES symbol
|
|
||||||
GLuint programId = program->programId();
|
|
||||||
glProgramBinaryOES(programId, cache->headers[shaderIndex].format,
|
|
||||||
cache->data + cache->headers[shaderIndex].index,
|
|
||||||
cache->headers[shaderIndex].size);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stores the shader program in the cache. Returns false if there's an error with the cache, or
|
|
||||||
if the cache is too small to hold the shader. */
|
|
||||||
static bool qt_cache_shader(const QGLShaderProgram *shader, const QGLContext *ctx, const QByteArray &md5Sum)
|
|
||||||
{
|
|
||||||
ShaderCacheSharedMemory *shm = shaderCacheSharedMemory();
|
|
||||||
if (!shm || !shm->isAttached())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
void *data = shm->data();
|
|
||||||
Q_ASSERT(data);
|
|
||||||
|
|
||||||
CachedShaders *cache = reinterpret_cast<CachedShaders *>(data);
|
|
||||||
|
|
||||||
ShaderCacheLocker locker(shm);
|
|
||||||
if (!locker.isLocked())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int cacheIdx = cache->shaderCount;
|
|
||||||
if (cacheIdx >= ShaderCacheMaxEntries) {
|
|
||||||
traceCacheOverflow("Qt OpenGL shader cache index overflow!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now that we have the lock on the shared memory, make sure no one
|
|
||||||
// inserted the shader already while we were unlocked
|
|
||||||
if (qt_cache_index_unlocked(md5Sum, cache) != -1)
|
|
||||||
return true; // already cached
|
|
||||||
|
|
||||||
shaderCacheDebug() << "Caching shader at index" << cacheIdx;
|
|
||||||
|
|
||||||
GLint binaryLength = 0;
|
|
||||||
glGetProgramiv(shader->programId(), GL_PROGRAM_BINARY_LENGTH_OES, &binaryLength);
|
|
||||||
|
|
||||||
if (!binaryLength) {
|
|
||||||
shaderCacheDebug() << "Unable to determine binary shader size!";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (binaryLength > cache->availableSize()) {
|
|
||||||
traceCacheOverflow("Qt OpenGL shader cache data overflow!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLsizei size = 0;
|
|
||||||
GLenum format = 0;
|
|
||||||
glGetProgramBinaryOES(shader->programId(), binaryLength, &size, &format,
|
|
||||||
cache->data + cache->dataSize);
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
shaderCacheDebug() << "Unable to get binary shader!";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cache->headers[cacheIdx].index = cache->dataSize;
|
|
||||||
cache->dataSize += binaryLength;
|
|
||||||
++cache->shaderCount;
|
|
||||||
cache->headers[cacheIdx].size = binaryLength;
|
|
||||||
cache->headers[cacheIdx].format = format;
|
|
||||||
|
|
||||||
memcpy(cache->headers[cacheIdx].md5Sum, md5Sum.constData(), 16);
|
|
||||||
|
|
||||||
shaderCacheDebug() << "cached shader size" << size
|
|
||||||
<< "format" << format
|
|
||||||
<< "binarySize" << binaryLength
|
|
||||||
<< "cache index" << cacheIdx
|
|
||||||
<< "data index" << cache->headers[cacheIdx].index;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
|
|
||||||
class CachedShader
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CachedShader(const QByteArray &fragSource, const QByteArray &vertexSource)
|
|
||||||
: cacheIdx(-1)
|
|
||||||
{
|
|
||||||
QCryptographicHash md5Hash(QCryptographicHash::Md5);
|
|
||||||
|
|
||||||
md5Hash.addData(fragSource);
|
|
||||||
md5Hash.addData(vertexSource);
|
|
||||||
|
|
||||||
md5Sum = md5Hash.result();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isCached()
|
|
||||||
{
|
|
||||||
return cacheIndex() != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cacheIndex()
|
|
||||||
{
|
|
||||||
if (cacheIdx != -1)
|
|
||||||
return cacheIdx;
|
|
||||||
cacheIdx = qt_cache_index(md5Sum);
|
|
||||||
return cacheIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool load(QGLShaderProgram *program, const QGLContext *ctx)
|
|
||||||
{
|
|
||||||
if (cacheIndex() == -1)
|
|
||||||
return false;
|
|
||||||
return qt_cached_shader(program, ctx, cacheIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool store(QGLShaderProgram *program, const QGLContext *ctx)
|
|
||||||
{
|
|
||||||
return qt_cache_shader(program, ctx, md5Sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QByteArray md5Sum;
|
|
||||||
int cacheIdx;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
@ -53,10 +53,6 @@
|
|||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
#if defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE) && defined(QT_OPENGL_ES_2)
|
|
||||||
# include "qglshadercache_meego_p.h"
|
|
||||||
#else
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
@ -88,4 +84,3 @@ public:
|
|||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
@ -41,8 +41,7 @@ HEADERS += qglshaderprogram.h \
|
|||||||
gl2paintengineex/qglengineshadersource_p.h \
|
gl2paintengineex/qglengineshadersource_p.h \
|
||||||
gl2paintengineex/qglcustomshaderstage_p.h \
|
gl2paintengineex/qglcustomshaderstage_p.h \
|
||||||
gl2paintengineex/qtextureglyphcache_gl_p.h \
|
gl2paintengineex/qtextureglyphcache_gl_p.h \
|
||||||
gl2paintengineex/qglshadercache_p.h \
|
gl2paintengineex/qglshadercache_p.h
|
||||||
gl2paintengineex/qglshadercache_meego_p.h
|
|
||||||
|
|
||||||
SOURCES += qglshaderprogram.cpp \
|
SOURCES += qglshaderprogram.cpp \
|
||||||
qgraphicsshadereffect.cpp \
|
qgraphicsshadereffect.cpp \
|
||||||
|
@ -440,12 +440,6 @@ QT_CLASS_LIB(QXmlResultItems, QtXmlPatterns, qxmlresultitems.h)
|
|||||||
QT_CLASS_LIB(QXmlSchema, QtXmlPatterns, qxmlschema.h)
|
QT_CLASS_LIB(QXmlSchema, QtXmlPatterns, qxmlschema.h)
|
||||||
QT_CLASS_LIB(QXmlSchemaValidator, QtXmlPatterns, qxmlschemavalidator.h)
|
QT_CLASS_LIB(QXmlSchemaValidator, QtXmlPatterns, qxmlschemavalidator.h)
|
||||||
QT_CLASS_LIB(QXmlSerializer, QtXmlPatterns, qxmlserializer.h)
|
QT_CLASS_LIB(QXmlSerializer, QtXmlPatterns, qxmlserializer.h)
|
||||||
QT_CLASS_LIB(QMeeGoFenceSync, QtMeeGoGraphicsSystemHelper, qmeegofencesync.h)
|
|
||||||
QT_CLASS_LIB(QMeeGoGraphicsSystemHelper, QtMeeGoGraphicsSystemHelper, qmeegographicssystemhelper.h)
|
|
||||||
QT_CLASS_LIB(QMeeGoLivePixmap, QtMeeGoGraphicsSystemHelper, qmeegolivepixmap.h)
|
|
||||||
QT_CLASS_LIB(QMeeGoOverlayWidget, QtMeeGoGraphicsSystemHelper, qmeegooverlaywidget.h)
|
|
||||||
QT_CLASS_LIB(QMeeGoRuntime, QtMeeGoGraphicsSystemHelper, qmeegoruntime.h)
|
|
||||||
QT_CLASS_LIB(QMeeGoSwitchEvent, QtMeeGoGraphicsSystemHelper, qmeegoswitchevent.h)
|
|
||||||
QT_CLASS_LIB(QAxBase, ActiveQt, qaxbase.h)
|
QT_CLASS_LIB(QAxBase, ActiveQt, qaxbase.h)
|
||||||
QT_CLASS_LIB(QAxObject, ActiveQt, qaxobject.h)
|
QT_CLASS_LIB(QAxObject, ActiveQt, qaxobject.h)
|
||||||
QT_CLASS_LIB(QAxScriptEngine, ActiveQt, qaxscript.h)
|
QT_CLASS_LIB(QAxScriptEngine, ActiveQt, qaxscript.h)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user