summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Rødal <sroedal@trolltech.com>2009-06-30 07:45:14 (GMT)
committerSamuel Rødal <sroedal@trolltech.com>2009-06-30 12:20:11 (GMT)
commit351e890aa13faac69a0ceaa8cb02660b2275cf82 (patch)
treecaf61d0d83735128390759638b20011d3b150cf7 /src
parent9dd82fcebc50ca802e9e24a50283152e1dc35508 (diff)
downloadQt-351e890aa13faac69a0ceaa8cb02660b2275cf82.zip
Qt-351e890aa13faac69a0ceaa8cb02660b2275cf82.tar.gz
Qt-351e890aa13faac69a0ceaa8cb02660b2275cf82.tar.bz2
Added custom shader hook to the GL 2 paint engine.
This will make it easier to implement pixmap filters, YUV->RGB conversions, etc in other parts of Qt.
Diffstat (limited to 'src')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp65
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h41
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp12
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h5
5 files changed, 107 insertions, 24 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 4b73ca9..068f804 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -49,6 +49,30 @@
QT_BEGIN_NAMESPACE
+QGLCustomShader::QGLCustomShader(QGLShader *shader)
+ : m_shader(shader)
+{
+}
+
+QGLCustomShader::~QGLCustomShader()
+{
+ delete m_shader;
+}
+
+void QGLCustomShader::updateUniforms(QGLShaderProgram *)
+{
+}
+
+void QGLCustomShader::setShader(QGLShader *shader)
+{
+ m_shader = shader;
+}
+
+QGLShader *QGLCustomShader::shader() const
+{
+ return m_shader;
+}
+
const char* QGLEngineShaderManager::qglEngineShaderSourceCode[] = {
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
@@ -66,7 +90,8 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
compositionMode(QPainter::CompositionMode_SourceOver),
blitShaderProg(0),
simpleShaderProg(0),
- currentShaderProg(0)
+ currentShaderProg(0),
+ customShader(0)
{
memset(compiledShaders, 0, sizeof(compiledShaders));
@@ -107,6 +132,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
code[MainFragmentShader] = qglslMainFragmentShader;
code[ImageSrcFragmentShader] = qglslImageSrcFragmentShader;
+ code[CustomSrcFragmentShader] = qglslCustomSrcFragmentShader;
code[ImageSrcWithPatternFragmentShader] = qglslImageSrcWithPatternFragmentShader;
code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader;
code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader;
@@ -228,7 +254,7 @@ void QGLEngineShaderManager::setDirty()
void QGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style)
{
- if (srcPixelType == PixelSrcType(style))
+ if (customShader || srcPixelType == PixelSrcType(style))
return;
srcPixelType = style;
@@ -237,13 +263,20 @@ void QGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style)
void QGLEngineShaderManager::setSrcPixelType(PixelSrcType type)
{
- if (srcPixelType == type)
+ if (customShader || srcPixelType == type)
return;
srcPixelType = type;
shaderProgNeedsChanging = true; //###
}
+void QGLEngineShaderManager::setCustomShader(QGLCustomShader *shader)
+{
+ srcPixelType = CustomSrc;
+ shaderProgNeedsChanging = true;
+ customShader = shader;
+}
+
void QGLEngineShaderManager::setTextureCoordsEnabled(bool enabled)
{
if (useTextureCoords == enabled)
@@ -338,6 +371,10 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
srcPixelFragShaderName = ImageSrcFragmentShader;
positionVertexShaderName = PositionOnlyVertexShader;
break;
+ case QGLEngineShaderManager::CustomSrc:
+ srcPixelFragShaderName = CustomSrcFragmentShader;
+ positionVertexShaderName = PositionOnlyVertexShader;
+ break;
case QGLEngineShaderManager::PatternSrc:
srcPixelFragShaderName = ImageSrcWithPatternFragmentShader;
positionVertexShaderName = PositionOnlyVertexShader;
@@ -381,7 +418,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;
@@ -483,6 +519,7 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
currentShaderProg = &prog;
currentShaderProg->program->enable();
shaderProgNeedsChanging = false;
+
return true;
}
}
@@ -496,6 +533,9 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
requiredProgram.program->addShader(requiredProgram.maskFragShader);
requiredProgram.program->addShader(requiredProgram.compositionFragShader);
+ if (customShader)
+ requiredProgram.program->addShader(customShader->shader());
+
// We have to bind the vertex attribute names before the program is linked:
requiredProgram.program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
if (useTextureCoords)
@@ -520,11 +560,20 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
qWarning() << error;
}
else {
- cachedPrograms.append(requiredProgram);
- // taking the address here is safe since
- // cachePrograms isn't resized anywhere else
- currentShaderProg = &cachedPrograms.last();
+ if (customShader) {
+ // don't cache custom shaders
+ customShaderProg = requiredProgram;
+ currentShaderProg = &customShaderProg;
+ } else {
+ cachedPrograms.append(requiredProgram);
+ // taking the address here is safe since
+ // cachePrograms isn't resized anywhere else
+ currentShaderProg = &cachedPrograms.last();
+ }
currentShaderProg->program->enable();
+
+ if (customShader)
+ customShader->updateUniforms(currentShaderProg->program);
}
shaderProgNeedsChanging = false;
return true;
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 34f0768..891776f 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -199,18 +199,19 @@
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:
+ The custom shader is passed to the shader manager as a partial fragment shader
+ by calling setCustomShader(). Qt's fragment pipeline will call the following
+ method name in the custom shader:
mediump vec4 customShader(sampler2d src, vec2 srcCoords)
- mediump vec4 customShaderWithDest(sampler2d dest, sampler2d src, vec2 srcCoords)
+
+ Transformations, clipping, opacity, and composition modes set using QPainter
+ will be respected when using the custom shader hook.
*/
@@ -227,6 +228,22 @@ QT_BEGIN_NAMESPACE
QT_MODULE(OpenGL)
+class Q_OPENGL_EXPORT QGLCustomShader
+{
+public:
+ QGLCustomShader(QGLShader *shader = 0);
+ virtual ~QGLCustomShader();
+
+ virtual void updateUniforms(QGLShaderProgram *program);
+
+ void setShader(QGLShader *shader);
+ QGLShader *shader() const;
+
+private:
+ Q_DISABLE_COPY(QGLCustomShader)
+
+ QGLShader *m_shader;
+};
struct QGLEngineShaderProg
{
@@ -259,7 +276,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:
@@ -271,7 +288,8 @@ public:
ImageSrc = Qt::TexturePattern+1,
NonPremultipliedImageSrc = Qt::TexturePattern+2,
PatternSrc = Qt::TexturePattern+3,
- TextureSrcWithPattern = Qt::TexturePattern+4
+ TextureSrcWithPattern = Qt::TexturePattern+4,
+ CustomSrc = Qt::TexturePattern + 5
};
// There are optimisations we can do, depending on the brush transform:
@@ -285,6 +303,8 @@ public:
void setMaskType(MaskType);
void setCompositionMode(QPainter::CompositionMode);
+ void setCustomShader(QGLCustomShader *shader);
+
uint getUniformIdentifier(const char *uniformName);
uint getUniformLocation(uint id);
@@ -322,6 +342,7 @@ public:
MainFragmentShader,
ImageSrcFragmentShader,
+ CustomSrcFragmentShader,
ImageSrcWithPatternFragmentShader,
NonPremultipliedImageSrcFragmentShader,
SolidBrushSrcFragmentShader,
@@ -366,7 +387,6 @@ public:
Q_ENUMS(ShaderName)
#endif
-
private:
QGLContext* ctx;
bool shaderProgNeedsChanging;
@@ -383,6 +403,9 @@ private:
QGLShaderProgram* simpleShaderProg;
QGLEngineShaderProg* currentShaderProg;
+ QGLEngineShaderProg customShaderProg;
+ QGLCustomShader* customShader;
+
// 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 4bf5d4c..a679a62 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -130,10 +130,6 @@ QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyph
QGLTextureGlyphCache::~QGLTextureGlyphCache()
{
- glDeleteFramebuffers(1, &m_fbo);
-
- if (m_width || m_height)
- glDeleteTextures(1, &m_texture);
}
void QGLTextureGlyphCache::createTextureData(int width, int height)
@@ -251,7 +247,7 @@ QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate()
void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
{
// glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit?
- if (id != -1 && id == lastTexture)
+ if (id != GLuint(-1) && id == lastTexture)
return;
lastTexture = id;
@@ -1605,4 +1601,10 @@ QOpenGL2PaintEngineState::~QOpenGL2PaintEngineState()
{
}
+QGLEngineShaderManager *QGL2PaintEngineEx::shaderManager() const
+{
+ Q_D(const QGL2PaintEngineEx);
+ return d->shaderManager;
+}
+
QT_END_NAMESPACE
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 0d28a49..f8d3b53 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:
@@ -133,6 +132,8 @@ public:
}
virtual void sync();
+ QGLEngineShaderManager *shaderManager() const;
+
private:
Q_DISABLE_COPY(QGL2PaintEngineEx)
};