diff options
Diffstat (limited to 'config.profiles/harmattan/patches/glshadercache.diff')
-rw-r--r-- | config.profiles/harmattan/patches/glshadercache.diff | 1003 |
1 files changed, 0 insertions, 1003 deletions
diff --git a/config.profiles/harmattan/patches/glshadercache.diff b/config.profiles/harmattan/patches/glshadercache.diff deleted file mode 100644 index 2c6ad9a3b5..0000000000 --- a/config.profiles/harmattan/patches/glshadercache.diff +++ /dev/null @@ -1,1003 +0,0 @@ -Index: qt-maemo-qtp/src/opengl/gl2paintengineex/qglengineshadermanager.cpp -=================================================================== ---- qt-maemo-qtp.orig/src/opengl/gl2paintengineex/qglengineshadermanager.cpp -+++ qt-maemo-qtp/src/opengl/gl2paintengineex/qglengineshadermanager.cpp -@@ -42,12 +42,12 @@ - #include "qglengineshadermanager_p.h" - #include "qglengineshadersource_p.h" - #include "qpaintengineex_opengl2_p.h" -+#include "qglshadercache_p.h" - - #if defined(QT_DEBUG) - #include <QMetaEnum> - #endif - -- - QT_BEGIN_NAMESPACE - - static void qt_shared_shaders_free(void *data) -@@ -165,62 +165,89 @@ - - QGLShader* fragShader; - QGLShader* vertexShader; -- QByteArray source; -+ QByteArray vertexSource; -+ QByteArray fragSource; - - // Compile up the simple shader: -- source.clear(); -- source.append(qShaderSnippets[MainVertexShader]); -- source.append(qShaderSnippets[PositionOnlyVertexShader]); -- vertexShader = new QGLShader(QGLShader::Vertex, context, this); -- if (!vertexShader->compileSourceCode(source)) -- qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile"); -- -- source.clear(); -- source.append(qShaderSnippets[MainFragmentShader]); -- source.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); -- fragShader = new QGLShader(QGLShader::Fragment, context, this); -- if (!fragShader->compileSourceCode(source)) -- qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile"); -+ vertexSource.append(qShaderSnippets[MainVertexShader]); -+ vertexSource.append(qShaderSnippets[PositionOnlyVertexShader]); -+ -+ fragSource.append(qShaderSnippets[MainFragmentShader]); -+ fragSource.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); - - simpleShaderProg = new QGLShaderProgram(context, this); -- simpleShaderProg->addShader(vertexShader); -- simpleShaderProg->addShader(fragShader); -- simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); -- simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); -- simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); -- simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); -+ -+ CachedShader simpleShaderCache(fragSource, vertexSource); -+ -+ bool inCache = simpleShaderCache.load(simpleShaderProg, context); -+ -+ if (!inCache) { -+ vertexShader = new QGLShader(QGLShader::Vertex, context, this); -+ if (!vertexShader->compileSourceCode(vertexSource)) -+ qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile"); -+ -+ fragShader = new QGLShader(QGLShader::Fragment, context, this); -+ if (!fragShader->compileSourceCode(fragSource)) -+ qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile"); -+ -+ simpleShaderProg->addShader(vertexShader); -+ simpleShaderProg->addShader(fragShader); -+ -+ simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); -+ simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); -+ simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); -+ simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); -+ } -+ - simpleShaderProg->link(); -- if (!simpleShaderProg->isLinked()) { -+ -+ if (simpleShaderProg->isLinked()) { -+ if (!inCache) -+ simpleShaderCache.store(simpleShaderProg, context); -+ } else { - qCritical() << "Errors linking simple shader:" - << simpleShaderProg->log(); - } - - // Compile the blit shader: -- source.clear(); -- source.append(qShaderSnippets[MainWithTexCoordsVertexShader]); -- source.append(qShaderSnippets[UntransformedPositionVertexShader]); -- vertexShader = new QGLShader(QGLShader::Vertex, context, this); -- if (!vertexShader->compileSourceCode(source)) -- qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile"); -- -- source.clear(); -- source.append(qShaderSnippets[MainFragmentShader]); -- source.append(qShaderSnippets[ImageSrcFragmentShader]); -- fragShader = new QGLShader(QGLShader::Fragment, context, this); -- if (!fragShader->compileSourceCode(source)) -- qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile"); -+ vertexSource.clear(); -+ vertexSource.append(qShaderSnippets[MainWithTexCoordsVertexShader]); -+ vertexSource.append(qShaderSnippets[UntransformedPositionVertexShader]); -+ -+ fragSource.clear(); -+ fragSource.append(qShaderSnippets[MainFragmentShader]); -+ fragSource.append(qShaderSnippets[ImageSrcFragmentShader]); - - blitShaderProg = new QGLShaderProgram(context, this); -- blitShaderProg->addShader(vertexShader); -- blitShaderProg->addShader(fragShader); -- blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); -- blitShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); -+ -+ CachedShader blitShaderCache(fragSource, vertexSource); -+ -+ inCache = blitShaderCache.load(blitShaderProg, context); -+ -+ if (!inCache) { -+ vertexShader = new QGLShader(QGLShader::Vertex, context, this); -+ if (!vertexShader->compileSourceCode(vertexSource)) -+ qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile"); -+ -+ fragShader = new QGLShader(QGLShader::Fragment, context, this); -+ if (!fragShader->compileSourceCode(fragSource)) -+ qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile"); -+ -+ blitShaderProg->addShader(vertexShader); -+ blitShaderProg->addShader(fragShader); -+ -+ blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); -+ blitShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); -+ } -+ - blitShaderProg->link(); -- if (!blitShaderProg->isLinked()) { -+ if (blitShaderProg->isLinked()) { -+ if (!inCache) -+ blitShaderCache.store(blitShaderProg, context); -+ } else { - qCritical() << "Errors linking blit shader:" -- << simpleShaderProg->log(); -+ << blitShaderProg->log(); - } -- - } - - QGLEngineSharedShaders::~QGLEngineSharedShaders() -@@ -262,99 +289,108 @@ - } - } - -- QGLShader *vertexShader = 0; -- QGLShader *fragShader = 0; -- QGLEngineShaderProg *newProg = 0; -- bool success = false; -+ QScopedPointer<QGLEngineShaderProg> newProg; - - do { -- QByteArray source; -+ QByteArray fragSource; - // Insert the custom stage before the srcPixel shader to work around an ATI driver bug - // where you cannot forward declare a function that takes a sampler as argument. - if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) -- source.append(prog.customStageSource); -- source.append(qShaderSnippets[prog.mainFragShader]); -- source.append(qShaderSnippets[prog.srcPixelFragShader]); -+ fragSource.append(prog.customStageSource); -+ fragSource.append(qShaderSnippets[prog.mainFragShader]); -+ fragSource.append(qShaderSnippets[prog.srcPixelFragShader]); - if (prog.compositionFragShader) -- source.append(qShaderSnippets[prog.compositionFragShader]); -+ fragSource.append(qShaderSnippets[prog.compositionFragShader]); - if (prog.maskFragShader) -- source.append(qShaderSnippets[prog.maskFragShader]); -- fragShader = new QGLShader(QGLShader::Fragment, ctxGuard.context(), this); -- QByteArray description; -+ fragSource.append(qShaderSnippets[prog.maskFragShader]); -+ -+ QByteArray vertexSource; -+ vertexSource.append(qShaderSnippets[prog.mainVertexShader]); -+ vertexSource.append(qShaderSnippets[prog.positionVertexShader]); -+ -+ QScopedPointer<QGLShaderProgram> shaderProgram(new QGLShaderProgram(ctxGuard.context(), this)); -+ -+ CachedShader shaderCache(fragSource, vertexSource); -+ bool inCache = shaderCache.load(shaderProgram.data(), ctxGuard.context()); -+ -+ if (!inCache) { -+ -+ QScopedPointer<QGLShader> fragShader(new QGLShader(QGLShader::Fragment, ctxGuard.context(), this)); -+ QByteArray description; - #if defined(QT_DEBUG) -- // Name the shader for easier debugging -- description.append("Fragment shader: main="); -- description.append(snippetNameStr(prog.mainFragShader)); -- description.append(", srcPixel="); -- description.append(snippetNameStr(prog.srcPixelFragShader)); -- if (prog.compositionFragShader) { -- description.append(", composition="); -- description.append(snippetNameStr(prog.compositionFragShader)); -- } -- if (prog.maskFragShader) { -- description.append(", mask="); -- description.append(snippetNameStr(prog.maskFragShader)); -- } -- fragShader->setObjectName(QString::fromLatin1(description)); -+ // Name the shader for easier debugging -+ description.append("Fragment shader: main="); -+ description.append(snippetNameStr(prog.mainFragShader)); -+ description.append(", srcPixel="); -+ description.append(snippetNameStr(prog.srcPixelFragShader)); -+ if (prog.compositionFragShader) { -+ description.append(", composition="); -+ description.append(snippetNameStr(prog.compositionFragShader)); -+ } -+ if (prog.maskFragShader) { -+ description.append(", mask="); -+ description.append(snippetNameStr(prog.maskFragShader)); -+ } -+ fragShader->setObjectName(QString::fromLatin1(description)); - #endif -- if (!fragShader->compileSourceCode(source)) { -- qWarning() << "Warning:" << description << "failed to compile!"; -- break; -- } -+ if (!fragShader->compileSourceCode(fragSource)) { -+ qWarning() << "Warning:" << description << "failed to compile!"; -+ break; -+ } - -- source.clear(); -- source.append(qShaderSnippets[prog.mainVertexShader]); -- source.append(qShaderSnippets[prog.positionVertexShader]); -- vertexShader = new QGLShader(QGLShader::Vertex, ctxGuard.context(), this); -+ QScopedPointer<QGLShader> vertexShader(new QGLShader(QGLShader::Vertex, ctxGuard.context(), this)); - #if defined(QT_DEBUG) -- // Name the shader for easier debugging -- description.clear(); -- description.append("Vertex shader: main="); -- description.append(snippetNameStr(prog.mainVertexShader)); -- description.append(", position="); -- description.append(snippetNameStr(prog.positionVertexShader)); -- vertexShader->setObjectName(QString::fromLatin1(description)); -+ // Name the shader for easier debugging -+ description.clear(); -+ description.append("Vertex shader: main="); -+ description.append(snippetNameStr(prog.mainVertexShader)); -+ description.append(", position="); -+ description.append(snippetNameStr(prog.positionVertexShader)); -+ vertexShader->setObjectName(QString::fromLatin1(description)); - #endif -- if (!vertexShader->compileSourceCode(source)) { -- qWarning() << "Warning:" << description << "failed to compile!"; -- break; -- } -+ if (!vertexShader->compileSourceCode(vertexSource)) { -+ qWarning() << "Warning:" << description << "failed to compile!"; -+ break; -+ } - -- newProg = new QGLEngineShaderProg(prog); -+ shaderProgram->addShader(vertexShader.take()); -+ shaderProgram->addShader(fragShader.take()); - -- // If the shader program's not found in the cache, create it now. -- newProg->program = new QGLShaderProgram(ctxGuard.context(), this); -- newProg->program->addShader(vertexShader); -- newProg->program->addShader(fragShader); -- -- // We have to bind the vertex attribute names before the program is linked: -- newProg->program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); -- if (newProg->useTextureCoords) -- newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); -- if (newProg->useOpacityAttribute) -- newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); -- if (newProg->usePmvMatrixAttribute) { -- newProg->program->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); -- newProg->program->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); -- newProg->program->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); -+ // We have to bind the vertex attribute names before the program is linked: -+ shaderProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); -+ if (prog.useTextureCoords) -+ shaderProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); -+ if (prog.useOpacityAttribute) -+ shaderProgram->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); -+ if (prog.usePmvMatrixAttribute) { -+ shaderProgram->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); -+ shaderProgram->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); -+ shaderProgram->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); -+ } - } - -+ newProg.reset(new QGLEngineShaderProg(prog)); -+ newProg->program = shaderProgram.take(); -+ - newProg->program->link(); -- if (!newProg->program->isLinked()) { -+ if (newProg->program->isLinked()) { -+ if (!inCache) -+ shaderCache.store(newProg->program, ctxGuard.context()); -+ } else { - QLatin1String none("none"); - QLatin1String br("\n"); - QString error; -- error = QLatin1String("Shader program failed to link,") -+ error = QLatin1String("Shader program failed to link,"); - #if defined(QT_DEBUG) -- + br -- + QLatin1String(" Shaders Used:") + br -- + QLatin1String(" ") + vertexShader->objectName() + QLatin1String(": ") + br -- + QLatin1String(vertexShader->sourceCode()) + br -- + QLatin1String(" ") + fragShader->objectName() + QLatin1String(": ") + br -- + QLatin1String(fragShader->sourceCode()) + br -+ error += QLatin1String("\n Shaders Used:\n"); -+ for (int i = 0; i < newProg->program->shaders().count(); ++i) { -+ QGLShader *shader = newProg->program->shaders().at(i); -+ error += QLatin1String(" ") + shader->objectName() + QLatin1String(": \n") -+ + QLatin1String(shader->sourceCode()) + br; -+ } - #endif -- + QLatin1String(" Error Log:\n") -- + QLatin1String(" ") + newProg->program->log(); -+ error += QLatin1String(" Error Log:\n") -+ + QLatin1String(" ") + newProg->program->log(); - qWarning() << error; - break; - } -@@ -376,26 +412,10 @@ - } - } - -- cachedPrograms.insert(0, newProg); -- -- success = true; -+ cachedPrograms.insert(0, newProg.data()); - } while (false); - -- // Clean up everything if we weren't successful -- if (!success) { -- if (newProg) { -- delete newProg; // Also deletes the QGLShaderProgram which in turn deletes the QGLShaders -- newProg = 0; -- } -- else { -- if (vertexShader) -- delete vertexShader; -- if (fragShader) -- delete fragShader; -- } -- } -- -- return newProg; -+ return newProg.take(); - } - - void QGLEngineSharedShaders::cleanupCustomStage(QGLCustomShaderStage* stage) -Index: qt-maemo-qtp/src/opengl/gl2paintengineex/qglshadercache_meego_p.h -=================================================================== ---- /dev/null -+++ qt-maemo-qtp/src/opengl/gl2paintengineex/qglshadercache_meego_p.h -@@ -0,0 +1,457 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -+** All rights reserved. -+** Contact: Nokia Corporation (qt-info@nokia.com) -+** -+** This file is part of the QtOpenGL module of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL$ -+** No Commercial Usage -+** This file contains pre-release code and may not be distributed. -+** You may use this file in accordance with the terms and conditions -+** contained in the Technology Preview License Agreement accompanying -+** this package. -+** -+** GNU Lesser General Public License Usage -+** Alternatively, this file may be used under the terms of the GNU Lesser -+** General Public License version 2.1 as published by the Free Software -+** Foundation and appearing in the file LICENSE.LGPL included in the -+** packaging of this file. Please review the following information to -+** ensure the GNU Lesser General Public License version 2.1 requirements -+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** In addition, as a special exception, Nokia gives you certain additional -+** rights. These rights are described in the Nokia Qt LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** If you have questions regarding the use of this file, please contact -+** Nokia at qt-info@nokia.com. -+** -+** -+** -+** -+** -+** -+** -+** -+** $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 -+ -+QT_BEGIN_HEADER -+ -+/* -+ 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 -+ -+QT_MODULE(OpenGL) -+ -+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 -+ -+QT_END_HEADER -+ -+#endif -+#endif -Index: qt-maemo-qtp/src/opengl/gl2paintengineex/qglshadercache_p.h -=================================================================== ---- /dev/null -+++ qt-maemo-qtp/src/opengl/gl2paintengineex/qglshadercache_p.h -@@ -0,0 +1,98 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -+** All rights reserved. -+** Contact: Nokia Corporation (qt-info@nokia.com) -+** -+** This file is part of the QtOpenGL module of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL$ -+** No Commercial Usage -+** This file contains pre-release code and may not be distributed. -+** You may use this file in accordance with the terms and conditions -+** contained in the Technology Preview License Agreement accompanying -+** this package. -+** -+** GNU Lesser General Public License Usage -+** Alternatively, this file may be used under the terms of the GNU Lesser -+** General Public License version 2.1 as published by the Free Software -+** Foundation and appearing in the file LICENSE.LGPL included in the -+** packaging of this file. Please review the following information to -+** ensure the GNU Lesser General Public License version 2.1 requirements -+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** In addition, as a special exception, Nokia gives you certain additional -+** rights. These rights are described in the Nokia Qt LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** If you have questions regarding the use of this file, please contact -+** Nokia at qt-info@nokia.com. -+** -+** -+** -+** -+** -+** -+** -+** -+** $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_P_H -+#define QGLSHADERCACHE_P_H -+ -+#include <QtCore/qglobal.h> -+ -+#if defined(QT_MEEGO_EXPERIMENTAL_SHADERCACHE) && defined(QT_OPENGL_ES_2) -+# include "qglshadercache_meego_p.h" -+#else -+ -+QT_BEGIN_HEADER -+ -+QT_BEGIN_NAMESPACE -+ -+QT_MODULE(OpenGL) -+ -+class QGLShaderProgram; -+class QGLContext; -+ -+class CachedShader -+{ -+public: -+ inline CachedShader(const QByteArray &, const QByteArray &) -+ {} -+ -+ inline bool isCached() -+ { -+ return false; -+ } -+ -+ inline bool load(QGLShaderProgram *, const QGLContext *) -+ { -+ return false; -+ } -+ -+ inline bool store(QGLShaderProgram *, const QGLContext *) -+ { -+ return false; -+ } -+}; -+ -+QT_END_NAMESPACE -+ -+QT_END_HEADER -+ -+#endif -+#endif -Index: qt-maemo-qtp/src/opengl/opengl.pro -=================================================================== ---- qt-maemo-qtp.orig/src/opengl/opengl.pro -+++ qt-maemo-qtp/src/opengl/opengl.pro -@@ -58,7 +58,9 @@ - gl2paintengineex/qglcustomshaderstage_p.h \ - gl2paintengineex/qtriangulatingstroker_p.h \ - gl2paintengineex/qtriangulator_p.h \ -- gl2paintengineex/qtextureglyphcache_gl_p.h -+ gl2paintengineex/qtextureglyphcache_gl_p.h \ -+ gl2paintengineex/qglshadercache_p.h \ -+ gl2paintengineex/qglshadercache_meego_p.h - - SOURCES += qglshaderprogram.cpp \ - qglpixmapfilter.cpp \ -Index: qt-maemo-qtp/src/opengl/util/meego/main.cpp -=================================================================== ---- /dev/null -+++ qt-maemo-qtp/src/opengl/util/meego/main.cpp -@@ -0,0 +1,48 @@ -+#include <QtCore/qdebug.h> -+ -+#define QT_DEBUG_SHADER_CACHE -+#define QT_MEEGO_EXPERIMENTAL_SHADERCACHE -+#define QT_OPENGL_ES_2 -+#define QT_BOOTSTRAPPED -+ -+typedef int GLsizei; -+typedef unsigned int GLenum; -+ -+#include "../../gl2paintengineex/qglshadercache_meego_p.h" -+ -+#include <stdlib.h> -+#include <stdio.h> -+ -+int main() -+{ -+ ShaderCacheSharedMemory shm; -+ -+ if (!shm.isAttached()) { -+ fprintf(stderr, "Unable to attach to shared memory\n"); -+ return EXIT_FAILURE; -+ } -+ -+ ShaderCacheLocker locker(&shm); -+ if (!locker.isLocked()) { -+ fprintf(stderr, "Unable to lock shared memory\n"); -+ return EXIT_FAILURE; -+ } -+ -+ void *data = shm.data(); -+ Q_ASSERT(data); -+ -+ CachedShaders *cache = reinterpret_cast<CachedShaders *>(data); -+ -+ for (int i = 0; i < cache->shaderCount; ++i) { -+ printf("Shader %d: %d bytes\n", i, cache->headers[i].size); -+ } -+ -+ printf("\nSummary:\n\n" -+ " Amount of cached shaders: %d\n" -+ " Bytes used: %d\n" -+ " Bytes available: %d\n", -+ cache->shaderCount, cache->dataSize, cache->availableSize()); -+ -+ return EXIT_SUCCESS; -+} -+ -Index: qt-maemo-qtp/src/opengl/util/meego/shader-cache-introspector.pro -=================================================================== ---- /dev/null -+++ qt-maemo-qtp/src/opengl/util/meego/shader-cache-introspector.pro -@@ -0,0 +1,7 @@ -+TEMPLATE = app -+ -+SOURCES += main.cpp -+ -+TARGET = shader-cache-introspector -+ -+QT = core |