summaryrefslogtreecommitdiffstats
path: root/config.profiles/harmattan/patches/glshadercache.diff
diff options
context:
space:
mode:
Diffstat (limited to 'config.profiles/harmattan/patches/glshadercache.diff')
-rw-r--r--config.profiles/harmattan/patches/glshadercache.diff1003
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