diff options
author | axis <qt-info@nokia.com> | 2009-08-21 13:51:34 (GMT) |
---|---|---|
committer | axis <qt-info@nokia.com> | 2009-08-21 13:51:34 (GMT) |
commit | f51a3bf2ed75b68e6746f9154f3e44e48723a7fc (patch) | |
tree | 6105a10f236a9478404d2a48d7c68fc3fc4da592 /src/opengl/gl2paintengineex | |
parent | afd7cfce7333635edc8d3637f81cc9c3023ee874 (diff) | |
parent | 4cc604be3fe96169c1dfdc05ff1b1a37e150e265 (diff) | |
download | Qt-f51a3bf2ed75b68e6746f9154f3e44e48723a7fc.zip Qt-f51a3bf2ed75b68e6746f9154f3e44e48723a7fc.tar.gz Qt-f51a3bf2ed75b68e6746f9154f3e44e48723a7fc.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt into master-s60
Conflicts:
src/gui/graphicsview/qgraphicsitem.cpp
src/gui/kernel/qwidget.cpp
src/gui/kernel/qwidget_p.h
Diffstat (limited to 'src/opengl/gl2paintengineex')
7 files changed, 413 insertions, 68 deletions
diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp new file mode 100644 index 0000000..a82caa0 --- /dev/null +++ b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qglcustomshaderstage_p.h" +#include "qglengineshadermanager_p.h" +#include "qpaintengineex_opengl2_p.h" +#include <private/qpainter_p.h> + +class QGLCustomShaderStagePrivate +{ +public: + QGLCustomShaderStagePrivate() : + m_manager(0) {} + + QGLEngineShaderManager* m_manager; + QByteArray m_source; +}; + + + + +QGLCustomShaderStage::QGLCustomShaderStage() + : d_ptr(new QGLCustomShaderStagePrivate) +{ +} + +QGLCustomShaderStage::~QGLCustomShaderStage() +{ + Q_D(QGLCustomShaderStage); + if (d->m_manager) + d->m_manager->removeCustomStage(this); +} + +void QGLCustomShaderStage::setUniformsDirty() +{ + Q_D(QGLCustomShaderStage); + if (d->m_manager) + d->m_manager->setDirty(); // ### Probably a bit overkill! +} + +bool QGLCustomShaderStage::setOnPainter(QPainter* p) +{ + Q_D(QGLCustomShaderStage); + if (p->paintEngine()->type() != QPaintEngine::OpenGL2) { + qWarning("QGLCustomShaderStage::setOnPainter() - paint engine not OpenGL2"); + return false; + } + + // Might as well go through the paint engine to get to the context + const QGLContext* ctx = static_cast<QGL2PaintEngineEx*>(p->paintEngine())->context(); + d->m_manager = QGLEngineShaderManager::managerForContext(ctx); + Q_ASSERT(d->m_manager); + + d->m_manager->setCustomStage(this); + return true; +} + +void QGLCustomShaderStage::removeFromPainter(QPainter* p) +{ + Q_D(QGLCustomShaderStage); + if (p->paintEngine()->type() != QPaintEngine::OpenGL2) + return; + + // Might as well go through the paint engine to get to the context + const QGLContext* ctx = static_cast<QGL2PaintEngineEx*>(p->paintEngine())->context(); + d->m_manager = QGLEngineShaderManager::managerForContext(ctx); + Q_ASSERT(d->m_manager); + + // Just set the stage to null, don't call removeCustomStage(). + // This should leave the program in a compiled/linked state + // if the next custom shader stage is this one again. + d->m_manager->setCustomStage(0); +} + +const char* QGLCustomShaderStage::source() const +{ + Q_D(const QGLCustomShaderStage); + return d->m_source.constData(); +} + +void QGLCustomShaderStage::setSource(const QByteArray& s) +{ + Q_D(QGLCustomShaderStage); + d->m_source = s; +} diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h new file mode 100644 index 0000000..70e9ff0 --- /dev/null +++ b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $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 QGL_CUSTOM_SHADER_STAGE_H +#define QGL_CUSTOM_SHADER_STAGE_H + +#include <QGLShaderProgram> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(OpenGL) + +class QGLCustomShaderStagePrivate; +class Q_OPENGL_EXPORT QGLCustomShaderStage +{ + Q_DECLARE_PRIVATE(QGLCustomShaderStage); +public: + QGLCustomShaderStage(); + virtual ~QGLCustomShaderStage(); + virtual void setUniforms(QGLShaderProgram*) = 0; + + void setUniformsDirty(); + + bool setOnPainter(QPainter*); + void removeFromPainter(QPainter*); + const char* source() const; + +protected: + void setSource(const QByteArray&); + +private: + QGLCustomShaderStagePrivate* d_ptr; +}; + + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 42b36a2..795c8b0 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -86,6 +86,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) maskType(NoMask), useTextureCoords(false), compositionMode(QPainter::CompositionMode_SourceOver), + customSrcStage(0), blitShaderProg(0), simpleShaderProg(0), currentShaderProg(0) @@ -131,6 +132,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) code[ImageSrcFragmentShader] = qglslImageSrcFragmentShader; code[ImageSrcWithPatternFragmentShader] = qglslImageSrcWithPatternFragmentShader; code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader; + code[CustomImageSrcFragmentShader] = ""; // Supplied by app. code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader; code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader; code[TextureBrushSrcWithPatternFragmentShader] = qglslTextureBrushSrcWithPatternFragmentShader; @@ -159,7 +161,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) #if defined(QT_DEBUG) // Check that all the elements have been filled: for (int i = 0; i < TotalShaderCount; ++i) { - if (qglEngineShaderSourceCode[i] == 0) { + if (i != CustomImageSrcFragmentShader && qglEngineShaderSourceCode[i] == 0) { int enumIndex = staticMetaObject.indexOfEnumerator("ShaderName"); QMetaEnum m = staticMetaObject.enumerator(enumIndex); @@ -308,6 +310,44 @@ void QGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode) shaderProgNeedsChanging = true; //### } +void QGLEngineShaderManager::setCustomStage(QGLCustomShaderStage* stage) +{ + // If the custom shader has changed, then destroy the previous compilation. + if (customSrcStage && stage && customSrcStage != stage) + removeCustomStage(customSrcStage); + + customSrcStage = stage; + shaderProgNeedsChanging = true; +} + +void QGLEngineShaderManager::shaderDestroyed(QObject *shader) +{ + // Remove any shader programs which has this as the srcPixel shader: + for (int i = 0; i < cachedPrograms.size(); ++i) { + if (cachedPrograms.at(i).srcPixelFragShader == shader) { + delete cachedPrograms.at(i).program; + cachedPrograms.removeAt(i--); + } + } + + shaderProgNeedsChanging = true; +} + +void QGLEngineShaderManager::removeCustomStage(QGLCustomShaderStage* stage) +{ + Q_UNUSED(stage); // Currently we only support one at a time... + + QGLShader *compiledShader = compiledShaders[CustomImageSrcFragmentShader]; + + if (!compiledShader) + return; + + compiledShaders[CustomImageSrcFragmentShader] = 0; + customSrcStage = 0; + shaderProgNeedsChanging = true; +} + + QGLShaderProgram* QGLEngineShaderManager::currentProgram() { return currentShaderProg->program; @@ -332,6 +372,12 @@ bool QGLEngineShaderManager::useCorrectShaderProg() if (!shaderProgNeedsChanging) return false; + bool useCustomSrc = customSrcStage != 0; + if (useCustomSrc && srcPixelType != QGLEngineShaderManager::ImageSrc) { + useCustomSrc = false; + qWarning("QGLEngineShaderManager - Ignoring custom shader stage for non image src"); + } + QGLEngineShaderProg requiredProgram; requiredProgram.program = 0; @@ -363,7 +409,11 @@ bool QGLEngineShaderManager::useCorrectShaderProg() qCritical("QGLEngineShaderManager::useCorrectShaderProg() - I'm scared, Qt::NoBrush style is set"); break; case QGLEngineShaderManager::ImageSrc: - srcPixelFragShaderName = ImageSrcFragmentShader; + srcPixelFragShaderName = useCustomSrc ? CustomImageSrcFragmentShader : ImageSrcFragmentShader; + positionVertexShaderName = PositionOnlyVertexShader; + break; + case QGLEngineShaderManager::NonPremultipliedImageSrc: + srcPixelFragShaderName = NonPremultipliedImageSrcFragmentShader; positionVertexShaderName = PositionOnlyVertexShader; break; case QGLEngineShaderManager::PatternSrc: @@ -375,10 +425,6 @@ bool QGLEngineShaderManager::useCorrectShaderProg() positionVertexShaderName = isAffine ? AffinePositionWithTextureBrushVertexShader : PositionWithTextureBrushVertexShader; break; - case QGLEngineShaderManager::NonPremultipliedImageSrc: - srcPixelFragShaderName = NonPremultipliedImageSrcFragmentShader; - positionVertexShaderName = PositionOnlyVertexShader; - break; case Qt::SolidPattern: srcPixelFragShaderName = SolidBrushSrcFragmentShader; positionVertexShaderName = PositionOnlyVertexShader; @@ -409,7 +455,6 @@ bool QGLEngineShaderManager::useCorrectShaderProg() requiredProgram.positionVertexShader = compiledShaders[positionVertexShaderName]; requiredProgram.srcPixelFragShader = compiledShaders[srcPixelFragShaderName]; - const bool hasCompose = compositionMode > QPainter::CompositionMode_Plus; const bool hasMask = maskType != QGLEngineShaderManager::NoMask; @@ -498,62 +543,63 @@ bool QGLEngineShaderManager::useCorrectShaderProg() else requiredProgram.compositionFragShader = 0; - // At this point, requiredProgram is fully populated so try to find the program in the cache + bool foundProgramInCache = false; for (int i = 0; i < cachedPrograms.size(); ++i) { - QGLEngineShaderProg &prog = cachedPrograms[i]; - if ( (prog.mainVertexShader == requiredProgram.mainVertexShader) - && (prog.positionVertexShader == requiredProgram.positionVertexShader) - && (prog.mainFragShader == requiredProgram.mainFragShader) - && (prog.srcPixelFragShader == requiredProgram.srcPixelFragShader) - && (prog.compositionFragShader == requiredProgram.compositionFragShader) ) - { - currentShaderProg = &prog; - currentShaderProg->program->enable(); - shaderProgNeedsChanging = false; - return true; + if (cachedPrograms[i] == requiredProgram) { + currentShaderProg = &cachedPrograms[i]; + foundProgramInCache = true; + break; } } - // Shader program not found in cache, create it now. - requiredProgram.program = new QGLShaderProgram(ctx, this); - requiredProgram.program->addShader(requiredProgram.mainVertexShader); - requiredProgram.program->addShader(requiredProgram.positionVertexShader); - requiredProgram.program->addShader(requiredProgram.mainFragShader); - requiredProgram.program->addShader(requiredProgram.srcPixelFragShader); - requiredProgram.program->addShader(requiredProgram.maskFragShader); - requiredProgram.program->addShader(requiredProgram.compositionFragShader); - - // We have to bind the vertex attribute names before the program is linked: - requiredProgram.program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - if (useTextureCoords) - requiredProgram.program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - - requiredProgram.program->link(); - if (!requiredProgram.program->isLinked()) { - QString error; - qWarning() << "Shader program failed to link," + // If the shader program's not found in the cache, create it now. + if (!foundProgramInCache) { + requiredProgram.program = new QGLShaderProgram(ctx, this); + requiredProgram.program->addShader(requiredProgram.mainVertexShader); + requiredProgram.program->addShader(requiredProgram.positionVertexShader); + requiredProgram.program->addShader(requiredProgram.mainFragShader); + requiredProgram.program->addShader(requiredProgram.srcPixelFragShader); + requiredProgram.program->addShader(requiredProgram.maskFragShader); + requiredProgram.program->addShader(requiredProgram.compositionFragShader); + + // We have to bind the vertex attribute names before the program is linked: + requiredProgram.program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + if (useTextureCoords) + requiredProgram.program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); + + requiredProgram.program->link(); + if (!requiredProgram.program->isLinked()) { + QString error; + qWarning() << "Shader program failed to link," #if defined(QT_DEBUG) - << '\n' - << " Shaders Used:" << '\n' - << " mainVertexShader = " << requiredProgram.mainVertexShader->objectName() << '\n' - << " positionVertexShader = " << requiredProgram.positionVertexShader->objectName() << '\n' - << " mainFragShader = " << requiredProgram.mainFragShader->objectName() << '\n' - << " srcPixelFragShader = " << requiredProgram.srcPixelFragShader->objectName() << '\n' - << " maskFragShader = " << requiredProgram.maskFragShader->objectName() << '\n' - << " compositionFragShader = "<< requiredProgram.compositionFragShader->objectName() << '\n' + << '\n' + << " Shaders Used:" << '\n' + << " mainVertexShader = " << requiredProgram.mainVertexShader->objectName() << '\n' + << " positionVertexShader = " << requiredProgram.positionVertexShader->objectName() << '\n' + << " mainFragShader = " << requiredProgram.mainFragShader->objectName() << '\n' + << " srcPixelFragShader = " << requiredProgram.srcPixelFragShader->objectName() << '\n' + << " maskFragShader = " << requiredProgram.maskFragShader->objectName() << '\n' + << " compositionFragShader = "<< requiredProgram.compositionFragShader->objectName() << '\n' #endif - << " Error Log:" << '\n' - << " " << requiredProgram.program->log(); - qWarning() << error; + << " Error Log:" << '\n' + << " " << requiredProgram.program->log(); + qWarning() << error; + delete requiredProgram.program; + } else { + cachedPrograms.append(requiredProgram); + // taking the address here is safe since + // cachePrograms isn't resized anywhere else + currentShaderProg = &cachedPrograms.last(); + } } - else { - cachedPrograms.append(requiredProgram); - // taking the address here is safe since - // cachePrograms isn't resized anywhere else - currentShaderProg = &cachedPrograms.last(); + + if (currentShaderProg) { currentShaderProg->program->enable(); + if (useCustomSrc) + customSrcStage->setUniforms(currentShaderProg->program); } + shaderProgNeedsChanging = false; return true; } @@ -563,8 +609,27 @@ void QGLEngineShaderManager::compileNamedShader(QGLEngineShaderManager::ShaderNa if (compiledShaders[name]) return; - QGLShader *newShader = new QGLShader(type, ctx, this); - newShader->compile(qglEngineShaderSourceCode[name]); + QGLShader *newShader; + + QByteArray source; + if (name == CustomImageSrcFragmentShader) { + source = customSrcStage->source(); + source += qglslCustomSrcFragmentShader; + + newShader = customShaderCache.object(source); + if (!newShader) { + newShader = new QGLShader(type, ctx, this); + newShader->compile(source); + customShaderCache.insert(source, newShader); + + connect(newShader, SIGNAL(destroyed(QObject *)), + this, SLOT(shaderDestroyed(QObject *))); + } + } else { + source = qglEngineShaderSourceCode[name]; + newShader = new QGLShader(type, ctx, this); + newShader->compile(source); + } #if defined(QT_DEBUG) // Name the shader for easier debugging diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index b314998..1ee75df 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -199,19 +199,23 @@ O = Global Opacity - CUSTOM SHADER CODE (idea, depricated) + CUSTOM SHADER CODE ================== The use of custom shader code is supported by the engine for drawImage and drawPixmap calls. This is implemented via hooks in the fragment pipeline. + The custom shader is passed to the engine as a partial fragment shader - (QGLCustomizedShader). The shader will implement a pre-defined method name - which Qt's fragment pipeline will call. There are two different hooks which - can be implemented as custom shader code: + (QGLCustomShaderStage). The shader will implement a pre-defined method name + which Qt's fragment pipeline will call: + + lowp vec4 customShader(sampler2d src, vec2 srcCoords) - mediump vec4 customShader(sampler2d src, vec2 srcCoords) - mediump vec4 customShaderWithDest(sampler2d dest, sampler2d src, vec2 srcCoords) + The provided src and srcCoords parameters can be used to sample from the + source image. + Transformations, clipping, opacity, and composition modes set using QPainter + will be respected when using the custom shader hook. */ #ifndef QGLENGINE_SHADER_MANAGER_H @@ -221,6 +225,7 @@ #include <QGLShaderProgram> #include <QPainter> #include <private/qgl_p.h> +#include <private/qglcustomshaderstage_p.h> QT_BEGIN_HEADER @@ -228,7 +233,6 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) - struct QGLEngineShaderProg { QGLShader* mainVertexShader; @@ -240,6 +244,17 @@ struct QGLEngineShaderProg QGLShaderProgram* program; QVector<uint> uniformLocations; + + bool operator==(const QGLEngineShaderProg& other) { + // We don't care about the program + return ( mainVertexShader == other.mainVertexShader && + positionVertexShader == other.positionVertexShader && + mainFragShader == other.mainFragShader && + srcPixelFragShader == other.srcPixelFragShader && + maskFragShader == other.maskFragShader && + compositionFragShader == other.compositionFragShader + ); + } }; /* @@ -260,7 +275,7 @@ struct QGLEngineCachedShaderProg static const GLuint QT_VERTEX_COORDS_ATTR = 0; static const GLuint QT_TEXTURE_COORDS_ATTR = 1; -class QGLEngineShaderManager : public QObject +class Q_OPENGL_EXPORT QGLEngineShaderManager : public QObject { Q_OBJECT public: @@ -305,6 +320,8 @@ public: void setUseGlobalOpacity(bool); void setMaskType(MaskType); void setCompositionMode(QPainter::CompositionMode); + void setCustomStage(QGLCustomShaderStage* stage); + void removeCustomStage(QGLCustomShaderStage* stage); uint getUniformLocation(Uniform id); @@ -344,8 +361,10 @@ public: MainFragmentShader, ImageSrcFragmentShader, + CustomSrcFragmentShader, ImageSrcWithPatternFragmentShader, NonPremultipliedImageSrcFragmentShader, + CustomImageSrcFragmentShader, SolidBrushSrcFragmentShader, TextureBrushSrcFragmentShader, TextureBrushSrcWithPatternFragmentShader, @@ -389,6 +408,8 @@ public: Q_ENUMS(ShaderName) #endif +private slots: + void shaderDestroyed(QObject *shader); private: QGLContext* ctx; @@ -401,6 +422,7 @@ private: MaskType maskType; bool useTextureCoords; QPainter::CompositionMode compositionMode; + QGLCustomShaderStage* customSrcStage; QGLShaderProgram* blitShaderProg; QGLShaderProgram* simpleShaderProg; @@ -408,6 +430,7 @@ private: // TODO: Possibly convert to a LUT QList<QGLEngineShaderProg> cachedPrograms; + QCache<QByteArray, QGLShader> customShaderCache; QGLShader* compiledShaders[TotalShaderCount]; diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index c80d6e1..cf930f3 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -290,6 +290,14 @@ static const char* const qglslImageSrcFragmentShader = "\ return texture2D(imageTexture, textureCoords); \ }"; +static const char* const qglslCustomSrcFragmentShader = "\ + varying highp vec2 textureCoords; \ + uniform sampler2D imageTexture; \ + lowp vec4 customShader(sampler2D texture, vec2 coords); \ + lowp vec4 srcPixel() { \ + return customShader(imageTexture, textureCoords); \ + }"; + static const char* const qglslImageSrcWithPatternFragmentShader = "\ varying highp vec2 textureCoords; \ uniform lowp vec4 patternColor; \ diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index c3f2de1..7a3fa56 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -720,6 +720,12 @@ void QGL2PaintEngineEx::sync() d->needsSync = true; } +const QGLContext *QGL2PaintEngineEx::context() +{ + Q_D(QGL2PaintEngineEx); + return d->ctx; +} + void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) { if (newMode == mode) @@ -1116,6 +1122,21 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel()); } +void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src) +{ + Q_D(QGL2PaintEngineEx); + ensureActive(); + d->transferMode(ImageDrawingMode); + + QGLContext *ctx = d->ctx; + glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); + glBindTexture(GL_TEXTURE_2D, textureId); + + d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, + state()->renderHints & QPainter::SmoothPixmapTransform, textureId); + d->drawTexture(dest, src, size, false); +} + void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem) { Q_D(QGL2PaintEngineEx); @@ -1720,6 +1741,14 @@ QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState() { } +QPixmapFilter *QGL2PaintEngineEx::createPixmapFilter(int type) const +{ + const QGLContext *ctx = QGLContext::currentContext(); + if (ctx) + return ctx->d_func()->createPixmapFilter(type); + return 0; +} + QT_END_NAMESPACE #include "qpaintengineex_opengl2.moc" diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index fa216bc..7b734e3 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -90,8 +90,7 @@ public: bool hasRectangleClip; }; - -class QGL2PaintEngineEx : public QPaintEngineEx +class Q_OPENGL_EXPORT QGL2PaintEngineEx : public QPaintEngineEx { Q_DECLARE_PRIVATE(QGL2PaintEngineEx) public: @@ -118,12 +117,13 @@ public: virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr); - virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor); + virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr); + virtual void drawTextItem(const QPointF &p, const QTextItem &textItem); - Type type() const { return OpenGL; } + Type type() const { return OpenGL2; } void setState(QPainterState *s); QPainterState *createState(QPainterState *orig) const; @@ -135,10 +135,15 @@ public: } virtual void sync(); + const QGLContext* context(); + + QPixmapFilter *createPixmapFilter(int type) const; + private: Q_DISABLE_COPY(QGL2PaintEngineEx) }; + class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate { Q_DECLARE_PUBLIC(QGL2PaintEngineEx) @@ -147,7 +152,7 @@ public: q(q_ptr), width(0), height(0), ctx(0), - currentBrush( &(q->state()->brush) ), + currentBrush(0), inverseScale(1), shaderManager(0) { } |