summaryrefslogtreecommitdiffstats
path: root/src/opengl/gl2paintengineex
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-07-28 10:25:55 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-07-28 12:19:18 (GMT)
commitdbdc54791e585f3c6bf62c1a091ef844a66483ba (patch)
tree75b5f14c4b1a8176b53b23d93f0b6f7dcc688365 /src/opengl/gl2paintengineex
parent610aa1737a206fe97628a3375a543400ea0761fa (diff)
parent0431548ddffc56f74cc60e7d341ade3920adefb1 (diff)
downloadQt-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')
-rw-r--r--src/opengl/gl2paintengineex/qglcustomshaderstage.cpp4
-rw-r--r--src/opengl/gl2paintengineex/qglcustomshaderstage_p.h3
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp37
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h22
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp23
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h9
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)
};