summaryrefslogtreecommitdiffstats
path: root/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
diff options
context:
space:
mode:
authorTom Cooksey <thomas.cooksey@nokia.com>2009-07-23 15:03:24 (GMT)
committerTom Cooksey <thomas.cooksey@nokia.com>2009-07-23 15:03:24 (GMT)
commit140ce8705f47a65bac32e804421b63d0c7b97d7d (patch)
tree5dfafd1cfe2d489ac2edd771e46385a4a7a748a1 /src/opengl/gl2paintengineex/qglengineshadermanager.cpp
parenta2d64535d011a47cb2bdf91002f9210cf6b656b1 (diff)
downloadQt-140ce8705f47a65bac32e804421b63d0c7b97d7d.zip
Qt-140ce8705f47a65bac32e804421b63d0c7b97d7d.tar.gz
Qt-140ce8705f47a65bac32e804421b63d0c7b97d7d.tar.bz2
Initial stab at a custom shader stage API
Diffstat (limited to 'src/opengl/gl2paintengineex/qglengineshadermanager.cpp')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp143
1 files changed, 95 insertions, 48 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index d7c91b8..327a699 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -308,6 +308,37 @@ void QGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode)
shaderProgNeedsChanging = true; //###
}
+void QGLEngineShaderManager::setCustomStage(QGLCustomShaderStage* stage)
+{
+ customSrcStage = stage;
+ 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;
+
+ // Remove any shader programs which has this as the srcPixel shader:
+ for (int i = 0; i < cachedPrograms.size(); ++i) {
+ QGLEngineShaderProg &prog = cachedPrograms[i];
+ if (prog.srcPixelFragShader == compiledShader) {
+ delete prog.program;
+ cachedPrograms.removeOne(prog);
+ break;
+ }
+ }
+
+ delete compiledShader;
+ compiledShaders[CustomImageSrcFragmentShader] = 0;
+ shaderProgNeedsChanging = true;
+}
+
+
QGLShaderProgram* QGLEngineShaderManager::currentProgram()
{
return currentShaderProg->program;
@@ -332,6 +363,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 +400,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 +416,6 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
positionVertexShaderName = isAffine ? AffinePositionWithTextureBrushVertexShader
: PositionWithTextureBrushVertexShader;
break;
- case QGLEngineShaderManager::NonPremultipliedImageSrc:
- srcPixelFragShaderName = NonPremultipliedImageSrcFragmentShader;
- positionVertexShaderName = PositionOnlyVertexShader;
- break;
case Qt::SolidPattern:
srcPixelFragShaderName = SolidBrushSrcFragmentShader;
positionVertexShaderName = PositionOnlyVertexShader;
@@ -500,60 +537,63 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
// 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.
+ while (!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;
- }
- else {
+ << " Error Log:" << '\n'
+ << " " << requiredProgram.program->log();
+ qWarning() << error;
+ delete requiredProgram.program;
+ break;
+ }
+
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;
}
@@ -564,7 +604,14 @@ void QGLEngineShaderManager::compileNamedShader(QGLEngineShaderManager::ShaderNa
return;
QGLShader *newShader = new QGLShader(type, ctx, this);
- newShader->compile(qglEngineShaderSourceCode[name]);
+
+ const char* sourceCode;
+ if (name == CustomImageSrcFragmentShader)
+ sourceCode = customSrcStage->source();
+ else
+ sourceCode = qglEngineShaderSourceCode[name];
+
+ newShader->compile(sourceCode);
#if defined(QT_DEBUG)
// Name the shader for easier debugging