diff options
author | Samuel Rødal <sroedal@trolltech.com> | 2009-07-28 10:25:55 (GMT) |
---|---|---|
committer | Samuel Rødal <sroedal@trolltech.com> | 2009-07-28 12:19:18 (GMT) |
commit | dbdc54791e585f3c6bf62c1a091ef844a66483ba (patch) | |
tree | 75b5f14c4b1a8176b53b23d93f0b6f7dcc688365 /src/opengl/gl2paintengineex | |
parent | 610aa1737a206fe97628a3375a543400ea0761fa (diff) | |
parent | 0431548ddffc56f74cc60e7d341ade3920adefb1 (diff) | |
download | Qt-dbdc54791e585f3c6bf62c1a091ef844a66483ba.zip Qt-dbdc54791e585f3c6bf62c1a091ef844a66483ba.tar.gz Qt-dbdc54791e585f3c6bf62c1a091ef844a66483ba.tar.bz2 |
Merge commit 'qt-graphics-team/pixmapfilters-redux' into kinetic-graphicseffect
Conflicts:
src/opengl/gl2paintengineex/qglengineshadermanager.cpp
src/opengl/gl2paintengineex/qglengineshadermanager_p.h
src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
Merge custom shader / GL blur pixmap filter implementation from graphics
team repo with implementation from kinetic graphics-team repo.
Diffstat (limited to 'src/opengl/gl2paintengineex')
7 files changed, 72 insertions, 34 deletions
diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp index bcd9f27..a82caa0 100644 --- a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp +++ b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp @@ -110,9 +110,9 @@ void QGLCustomShaderStage::removeFromPainter(QPainter* p) d->m_manager->setCustomStage(0); } -const char* QGLCustomShaderStage::source() +const char* QGLCustomShaderStage::source() const { - Q_D(QGLCustomShaderStage); + Q_D(const QGLCustomShaderStage); return d->m_source.constData(); } diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h index 659f7ba..70e9ff0 100644 --- a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h +++ b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h @@ -71,9 +71,10 @@ public: virtual void setUniforms(QGLShaderProgram*) = 0; void setUniformsDirty(); + bool setOnPainter(QPainter*); void removeFromPainter(QPainter*); - const char* source(); + const char* source() const; protected: void setSource(const QByteArray&); diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 848a7f1..dab1257 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -87,7 +87,6 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) useTextureCoords(false), compositionMode(QPainter::CompositionMode_SourceOver), customSrcStage(0), - customSrcStagePrev(0), blitShaderProg(0), simpleShaderProg(0), currentShaderProg(0) @@ -162,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); @@ -314,10 +313,9 @@ void QGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode) void QGLEngineShaderManager::setCustomStage(QGLCustomShaderStage* stage) { // If the custom shader has changed, then destroy the previous compilation. - if (customSrcStagePrev && stage && customSrcStagePrev != stage) - removeCustomStage(customSrcStagePrev); + if (customSrcStage && stage && customSrcStage != stage) + removeCustomStage(customSrcStage); - customSrcStagePrev = customSrcStage; customSrcStage = stage; shaderProgNeedsChanging = true; } @@ -326,7 +324,7 @@ void QGLEngineShaderManager::removeCustomStage(QGLCustomShaderStage* stage) { Q_UNUSED(stage); // Currently we only support one at a time... - QGLShader* compiledShader = compiledShaders[CustomImageSrcFragmentShader]; + QGLShader *compiledShader = compiledShaders[CustomImageSrcFragmentShader]; if (!compiledShader) return; @@ -341,10 +339,8 @@ void QGLEngineShaderManager::removeCustomStage(QGLCustomShaderStage* stage) } } - delete compiledShader; compiledShaders[CustomImageSrcFragmentShader] = 0; customSrcStage = 0; - customSrcStagePrev = 0; shaderProgNeedsChanging = true; } @@ -456,7 +452,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; @@ -545,7 +540,6 @@ 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) { @@ -612,15 +606,24 @@ void QGLEngineShaderManager::compileNamedShader(QGLEngineShaderManager::ShaderNa if (compiledShaders[name]) return; - QGLShader *newShader = new QGLShader(type, ctx, this); + QGLShader *newShader; - const char* sourceCode; - if (name == CustomImageSrcFragmentShader) - sourceCode = customSrcStage->source(); - else - sourceCode = qglEngineShaderSourceCode[name]; + QByteArray source; + if (name == CustomImageSrcFragmentShader) { + source = customSrcStage->source(); + source += qglslCustomSrcFragmentShader; - newShader->compile(sourceCode); + newShader = customShaderCache.object(source); + if (!newShader) { + newShader = new QGLShader(type, ctx, this); + newShader->compile(source); + customShaderCache.insert(source, newShader); + } + } 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 9d881cc..69574ba 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -199,23 +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 (QGLCustomShaderStage). The shader will implement a pre-defined method name which Qt's fragment pipeline will call: - lowp vec4 customShader() - - Depending on the custom type, the custom shader has a small API it can use - to read pixels. The basic custom type is for image/pixmap drawing and thus - can use the following to sample the src texture (non-premultiplied) + lowp vec4 customShader(sampler2d src, vec2 srcCoords) - lowp vec4 QSampleSrcPixel(mediump vec2 coords) + 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 @@ -233,7 +233,6 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) - struct QGLEngineShaderProg { QGLShader* mainVertexShader; @@ -276,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: @@ -362,6 +361,7 @@ public: MainFragmentShader, ImageSrcFragmentShader, + CustomSrcFragmentShader, ImageSrcWithPatternFragmentShader, NonPremultipliedImageSrcFragmentShader, CustomImageSrcFragmentShader, @@ -408,7 +408,6 @@ public: Q_ENUMS(ShaderName) #endif - private: QGLContext* ctx; bool shaderProgNeedsChanging; @@ -421,12 +420,13 @@ private: bool useTextureCoords; QPainter::CompositionMode compositionMode; QGLCustomShaderStage* customSrcStage; - QGLCustomShaderStage* customSrcStagePrev; QGLShaderProgram* blitShaderProg; QGLShaderProgram* simpleShaderProg; QGLEngineShaderProg* currentShaderProg; + QCache<QByteArray, QGLShader> customShaderCache; + // TODO: Possibly convert to a LUT QList<QGLEngineShaderProg> cachedPrograms; diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index 4e32f91..e379aa3 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 b04c7e6..db306a5 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1092,6 +1092,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); @@ -1636,6 +1651,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 21c296d..3ff2dca 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -88,8 +88,7 @@ public: bool canRestoreClip; }; - -class QGL2PaintEngineEx : public QPaintEngineEx +class Q_OPENGL_EXPORT QGL2PaintEngineEx : public QPaintEngineEx { Q_DECLARE_PRIVATE(QGL2PaintEngineEx) public: @@ -116,9 +115,10 @@ 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 OpenGL2; } @@ -134,6 +134,9 @@ public: virtual void sync(); const QGLContext* context(); + + QPixmapFilter *createPixmapFilter(int type) const; + private: Q_DISABLE_COPY(QGL2PaintEngineEx) }; |