summaryrefslogtreecommitdiffstats
path: root/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/gl2paintengineex/qglengineshadermanager.cpp')
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp447
1 files changed, 229 insertions, 218 deletions
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index d48a7b6..e7c11fd 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -49,47 +49,38 @@
QT_BEGIN_NAMESPACE
-static void QGLEngineShaderManager_free(void *ptr)
+static void qt_shared_shaders_free(void *data)
{
- delete reinterpret_cast<QGLEngineShaderManager *>(ptr);
+ delete reinterpret_cast<QGLEngineSharedShaders *>(data);
}
-Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shader_managers, (QGLEngineShaderManager_free))
+Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shared_shaders, (qt_shared_shaders_free))
-QGLEngineShaderManager *QGLEngineShaderManager::managerForContext(const QGLContext *context)
+QGLEngineSharedShaders *QGLEngineSharedShaders::shadersForContext(const QGLContext *context)
{
- QGLEngineShaderManager *p = reinterpret_cast<QGLEngineShaderManager *>(qt_shader_managers()->value(context));
+ QGLEngineSharedShaders *p = reinterpret_cast<QGLEngineSharedShaders *>(qt_shared_shaders()->value(context));
if (!p) {
QGLContext *oldContext = const_cast<QGLContext *>(QGLContext::currentContext());
if (oldContext != context)
const_cast<QGLContext *>(context)->makeCurrent();
- p = new QGLEngineShaderManager(const_cast<QGLContext *>(context));
- qt_shader_managers()->insert(context, p);
+ qt_shared_shaders()->insert(context, p = new QGLEngineSharedShaders(context));
if (oldContext && oldContext != context)
oldContext->makeCurrent();
}
return p;
}
-const char* QGLEngineShaderManager::qglEngineShaderSourceCode[] = {
+const char* QGLEngineSharedShaders::qglEngineShaderSourceCode[] = {
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0
};
-QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
- : ctx(context),
- shaderProgNeedsChanging(true),
- srcPixelType(Qt::NoBrush),
- useGlobalOpacity(false),
- maskType(NoMask),
- useTextureCoords(false),
- compositionMode(QPainter::CompositionMode_SourceOver),
- customSrcStage(0),
- blitShaderProg(0),
- simpleShaderProg(0),
- currentShaderProg(0)
+QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
+ : ctx(QGLContextPrivate::contextGroup(context))
+ , blitShaderProg(0)
+ , simpleShaderProg(0)
{
memset(compiledShaders, 0, sizeof(compiledShaders));
@@ -174,7 +165,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
}
// Compile up the simple shader:
- simpleShaderProg = new QGLShaderProgram(ctx, this);
+ simpleShaderProg = new QGLShaderProgram(context, this);
compileNamedShader(MainVertexShader, QGLShader::PartialVertexShader);
compileNamedShader(PositionOnlyVertexShader, QGLShader::PartialVertexShader);
compileNamedShader(MainFragmentShader, QGLShader::PartialFragmentShader);
@@ -191,7 +182,7 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
}
// Compile the blit shader:
- blitShaderProg = new QGLShaderProgram(ctx, this);
+ blitShaderProg = new QGLShaderProgram(context, this);
compileNamedShader(MainWithTexCoordsVertexShader, QGLShader::PartialVertexShader);
compileNamedShader(UntransformedPositionVertexShader, QGLShader::PartialVertexShader);
compileNamedShader(MainFragmentShader, QGLShader::PartialFragmentShader);
@@ -209,6 +200,145 @@ QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
}
}
+void QGLEngineSharedShaders::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--);
+ }
+ }
+
+ emit shaderProgNeedsChanging();
+}
+
+QGLShader *QGLEngineSharedShaders::compileNamedShader(ShaderName name, QGLShader::ShaderType type)
+{
+ Q_ASSERT(name != CustomImageSrcFragmentShader);
+ if (compiledShaders[name])
+ return compiledShaders[name];
+
+ QByteArray source = qglEngineShaderSourceCode[name];
+ QGLShader *newShader = new QGLShader(type, ctx->context(), this);
+ newShader->compile(source);
+
+#if defined(QT_DEBUG)
+ // Name the shader for easier debugging
+ QMetaEnum m = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("ShaderName"));
+ newShader->setObjectName(QLatin1String(m.valueToKey(name)));
+#endif
+
+ compiledShaders[name] = newShader;
+ return newShader;
+}
+
+QGLShader *QGLEngineSharedShaders::compileCustomShader(QGLCustomShaderStage *stage, QGLShader::ShaderType type)
+{
+ QByteArray source = stage->source();
+ source += qglslCustomSrcFragmentShader;
+
+ QGLShader *newShader = customShaderCache.object(source);
+ if (newShader)
+ return newShader;
+
+ newShader = new QGLShader(type, ctx->context(), this);
+ newShader->compile(source);
+ customShaderCache.insert(source, newShader);
+
+ connect(newShader, SIGNAL(destroyed(QObject *)),
+ this, SLOT(shaderDestroyed(QObject *)));
+
+#if defined(QT_DEBUG)
+ // Name the shader for easier debugging
+ QMetaEnum m = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("ShaderName"));
+ newShader->setObjectName(QLatin1String(m.valueToKey(CustomImageSrcFragmentShader)));
+#endif
+
+ return newShader;
+}
+
+// The address returned here will only be valid until next time this function is called.
+QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineShaderProg &prog)
+{
+ for (int i = 0; i < cachedPrograms.size(); ++i) {
+ if (cachedPrograms[i] == prog)
+ return &cachedPrograms[i];
+ }
+
+ cachedPrograms.append(prog);
+ QGLEngineShaderProg &cached = cachedPrograms.last();
+
+ // If the shader program's not found in the cache, create it now.
+ cached.program = new QGLShaderProgram(ctx->context(), this);
+ cached.program->addShader(cached.mainVertexShader);
+ cached.program->addShader(cached.positionVertexShader);
+ cached.program->addShader(cached.mainFragShader);
+ cached.program->addShader(cached.srcPixelFragShader);
+ cached.program->addShader(cached.maskFragShader);
+ cached.program->addShader(cached.compositionFragShader);
+
+ // We have to bind the vertex attribute names before the program is linked:
+ cached.program->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
+ cached.program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
+
+ cached.program->link();
+ if (!cached.program->isLinked()) {
+ QLatin1String none("none");
+ QLatin1String br("\n");
+ QString error;
+ error = QLatin1String("Shader program failed to link,")
+#if defined(QT_DEBUG)
+ + br
+ + QLatin1String(" Shaders Used:\n")
+ + QLatin1String(" mainVertexShader = ")
+ + (cached.mainVertexShader ?
+ cached.mainVertexShader->objectName() : none) + br
+ + QLatin1String(" positionVertexShader = ")
+ + (cached.positionVertexShader ?
+ cached.positionVertexShader->objectName() : none) + br
+ + QLatin1String(" mainFragShader = ")
+ + (cached.mainFragShader ?
+ cached.mainFragShader->objectName() : none) + br
+ + QLatin1String(" srcPixelFragShader = ")
+ + (cached.srcPixelFragShader ?
+ cached.srcPixelFragShader->objectName() : none) + br
+ + QLatin1String(" maskFragShader = ")
+ + (cached.maskFragShader ?
+ cached.maskFragShader->objectName() : none) + br
+ + QLatin1String(" compositionFragShader = ")
+ + (cached.compositionFragShader ?
+ cached.compositionFragShader->objectName() : none) + br
+#endif
+ + QLatin1String(" Error Log:\n")
+ + QLatin1String(" ") + cached.program->log();
+ qWarning() << error;
+ delete cached.program;
+ cachedPrograms.removeLast();
+ return 0;
+ } else {
+ // taking the address here is safe since
+ // cachePrograms isn't resized anywhere else
+ return &cached;
+ }
+}
+
+QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context)
+ : ctx(context),
+ shaderProgNeedsChanging(true),
+ srcPixelType(Qt::NoBrush),
+ useGlobalOpacity(false),
+ maskType(NoMask),
+ useTextureCoords(false),
+ compositionMode(QPainter::CompositionMode_SourceOver),
+ customSrcStage(0),
+ currentShaderProg(0),
+ customShader(0)
+{
+ sharedShaders = QGLEngineSharedShaders::shadersForContext(context);
+ connect(sharedShaders, SIGNAL(shaderProgNeedsChanging()), this, SLOT(shaderProgNeedsChangingSlot()));
+}
+
QGLEngineShaderManager::~QGLEngineShaderManager()
{
//###
@@ -312,24 +442,8 @@ void QGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode)
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--);
- }
- }
-
+ customShader = 0; // Will be compiled from 'customSrcStage' later.
shaderProgNeedsChanging = true;
}
@@ -337,13 +451,8 @@ 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;
+ customShader = 0;
shaderProgNeedsChanging = true;
}
@@ -355,12 +464,12 @@ QGLShaderProgram* QGLEngineShaderManager::currentProgram()
QGLShaderProgram* QGLEngineShaderManager::simpleProgram()
{
- return simpleShaderProg;
+ return sharedShaders->simpleProgram();
}
QGLShaderProgram* QGLEngineShaderManager::blitProgram()
{
- return blitShaderProg;
+ return sharedShaders->blitProgram();
}
@@ -382,26 +491,25 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
requiredProgram.program = 0;
// Choose vertex shader main function
- QGLEngineShaderManager::ShaderName mainVertexShaderName = InvalidShaderName;
+ QGLEngineSharedShaders::ShaderName mainVertexShaderName = QGLEngineSharedShaders::InvalidShaderName;
if (useTextureCoords)
- mainVertexShaderName = MainWithTexCoordsVertexShader;
+ mainVertexShaderName = QGLEngineSharedShaders::MainWithTexCoordsVertexShader;
else
- mainVertexShaderName = MainVertexShader;
- compileNamedShader(mainVertexShaderName, QGLShader::PartialVertexShader);
- requiredProgram.mainVertexShader = compiledShaders[mainVertexShaderName];
+ mainVertexShaderName = QGLEngineSharedShaders::MainVertexShader;
+ requiredProgram.mainVertexShader = sharedShaders->compileNamedShader(mainVertexShaderName, QGLShader::PartialVertexShader);
// Choose vertex shader shader position function (which typically also sets
// varyings) and the source pixel (srcPixel) fragment shader function:
- QGLEngineShaderManager::ShaderName positionVertexShaderName = InvalidShaderName;
- QGLEngineShaderManager::ShaderName srcPixelFragShaderName = InvalidShaderName;
+ QGLEngineSharedShaders::ShaderName positionVertexShaderName = QGLEngineSharedShaders::InvalidShaderName;
+ QGLEngineSharedShaders::ShaderName srcPixelFragShaderName = QGLEngineSharedShaders::InvalidShaderName;
bool isAffine = brushTransform.isAffine();
if ( (srcPixelType >= Qt::Dense1Pattern) && (srcPixelType <= Qt::DiagCrossPattern) ) {
if (isAffine)
- positionVertexShaderName = AffinePositionWithPatternBrushVertexShader;
+ positionVertexShaderName = QGLEngineSharedShaders::AffinePositionWithPatternBrushVertexShader;
else
- positionVertexShaderName = PositionWithPatternBrushVertexShader;
+ positionVertexShaderName = QGLEngineSharedShaders::PositionWithPatternBrushVertexShader;
- srcPixelFragShaderName = PatternBrushSrcFragmentShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::PatternBrushSrcFragmentShader;
}
else switch (srcPixelType) {
default:
@@ -409,204 +517,143 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
qCritical("QGLEngineShaderManager::useCorrectShaderProg() - I'm scared, Qt::NoBrush style is set");
break;
case QGLEngineShaderManager::ImageSrc:
- srcPixelFragShaderName = useCustomSrc ? CustomImageSrcFragmentShader : ImageSrcFragmentShader;
- positionVertexShaderName = PositionOnlyVertexShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::ImageSrcFragmentShader;
+ positionVertexShaderName = QGLEngineSharedShaders::PositionOnlyVertexShader;
break;
case QGLEngineShaderManager::NonPremultipliedImageSrc:
- srcPixelFragShaderName = NonPremultipliedImageSrcFragmentShader;
- positionVertexShaderName = PositionOnlyVertexShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::NonPremultipliedImageSrcFragmentShader;
+ positionVertexShaderName = QGLEngineSharedShaders::PositionOnlyVertexShader;
break;
case QGLEngineShaderManager::PatternSrc:
- srcPixelFragShaderName = ImageSrcWithPatternFragmentShader;
- positionVertexShaderName = PositionOnlyVertexShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::ImageSrcWithPatternFragmentShader;
+ positionVertexShaderName = QGLEngineSharedShaders::PositionOnlyVertexShader;
break;
case QGLEngineShaderManager::TextureSrcWithPattern:
- srcPixelFragShaderName = TextureBrushSrcWithPatternFragmentShader;
- positionVertexShaderName = isAffine ? AffinePositionWithTextureBrushVertexShader
- : PositionWithTextureBrushVertexShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::TextureBrushSrcWithPatternFragmentShader;
+ positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader
+ : QGLEngineSharedShaders::PositionWithTextureBrushVertexShader;
break;
case Qt::SolidPattern:
- srcPixelFragShaderName = SolidBrushSrcFragmentShader;
- positionVertexShaderName = PositionOnlyVertexShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::SolidBrushSrcFragmentShader;
+ positionVertexShaderName = QGLEngineSharedShaders::PositionOnlyVertexShader;
break;
case Qt::LinearGradientPattern:
- srcPixelFragShaderName = LinearGradientBrushSrcFragmentShader;
- positionVertexShaderName = isAffine ? AffinePositionWithLinearGradientBrushVertexShader
- : PositionWithLinearGradientBrushVertexShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::LinearGradientBrushSrcFragmentShader;
+ positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithLinearGradientBrushVertexShader
+ : QGLEngineSharedShaders::PositionWithLinearGradientBrushVertexShader;
break;
case Qt::ConicalGradientPattern:
- srcPixelFragShaderName = ConicalGradientBrushSrcFragmentShader;
- positionVertexShaderName = isAffine ? AffinePositionWithConicalGradientBrushVertexShader
- : PositionWithConicalGradientBrushVertexShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::ConicalGradientBrushSrcFragmentShader;
+ positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithConicalGradientBrushVertexShader
+ : QGLEngineSharedShaders::PositionWithConicalGradientBrushVertexShader;
break;
case Qt::RadialGradientPattern:
- srcPixelFragShaderName = RadialGradientBrushSrcFragmentShader;
- positionVertexShaderName = isAffine ? AffinePositionWithRadialGradientBrushVertexShader
- : PositionWithRadialGradientBrushVertexShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::RadialGradientBrushSrcFragmentShader;
+ positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithRadialGradientBrushVertexShader
+ : QGLEngineSharedShaders::PositionWithRadialGradientBrushVertexShader;
break;
case Qt::TexturePattern:
- srcPixelFragShaderName = TextureBrushSrcFragmentShader;
- positionVertexShaderName = isAffine ? AffinePositionWithTextureBrushVertexShader
- : PositionWithTextureBrushVertexShader;
+ srcPixelFragShaderName = QGLEngineSharedShaders::TextureBrushSrcFragmentShader;
+ positionVertexShaderName = isAffine ? QGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader
+ : QGLEngineSharedShaders::PositionWithTextureBrushVertexShader;
break;
};
- compileNamedShader(positionVertexShaderName, QGLShader::PartialVertexShader);
- compileNamedShader(srcPixelFragShaderName, QGLShader::PartialFragmentShader);
- requiredProgram.positionVertexShader = compiledShaders[positionVertexShaderName];
- requiredProgram.srcPixelFragShader = compiledShaders[srcPixelFragShaderName];
+ requiredProgram.positionVertexShader = sharedShaders->compileNamedShader(positionVertexShaderName, QGLShader::PartialVertexShader);
+ if (useCustomSrc) {
+ if (!customShader)
+ customShader = sharedShaders->compileCustomShader(customSrcStage, QGLShader::PartialFragmentShader);
+ requiredProgram.srcPixelFragShader = customShader;
+ } else {
+ requiredProgram.srcPixelFragShader = sharedShaders->compileNamedShader(srcPixelFragShaderName, QGLShader::PartialFragmentShader);
+ }
const bool hasCompose = compositionMode > QPainter::CompositionMode_Plus;
const bool hasMask = maskType != QGLEngineShaderManager::NoMask;
// Choose fragment shader main function:
- QGLEngineShaderManager::ShaderName mainFragShaderName;
+ QGLEngineSharedShaders::ShaderName mainFragShaderName;
if (hasCompose && hasMask && useGlobalOpacity)
- mainFragShaderName = MainFragmentShader_CMO;
+ mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_CMO;
if (hasCompose && hasMask && !useGlobalOpacity)
- mainFragShaderName = MainFragmentShader_CM;
+ mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_CM;
if (!hasCompose && hasMask && useGlobalOpacity)
- mainFragShaderName = MainFragmentShader_MO;
+ mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_MO;
if (!hasCompose && hasMask && !useGlobalOpacity)
- mainFragShaderName = MainFragmentShader_M;
+ mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_M;
if (hasCompose && !hasMask && useGlobalOpacity)
- mainFragShaderName = MainFragmentShader_CO;
+ mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_CO;
if (hasCompose && !hasMask && !useGlobalOpacity)
- mainFragShaderName = MainFragmentShader_C;
+ mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_C;
if (!hasCompose && !hasMask && useGlobalOpacity)
- mainFragShaderName = MainFragmentShader_O;
+ mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader_O;
if (!hasCompose && !hasMask && !useGlobalOpacity)
- mainFragShaderName = MainFragmentShader;
+ mainFragShaderName = QGLEngineSharedShaders::MainFragmentShader;
- compileNamedShader(mainFragShaderName, QGLShader::PartialFragmentShader);
- requiredProgram.mainFragShader = compiledShaders[mainFragShaderName];
+ requiredProgram.mainFragShader = sharedShaders->compileNamedShader(mainFragShaderName, QGLShader::PartialFragmentShader);
if (hasMask) {
- QGLEngineShaderManager::ShaderName maskShaderName = QGLEngineShaderManager::InvalidShaderName;
+ QGLEngineSharedShaders::ShaderName maskShaderName = QGLEngineSharedShaders::InvalidShaderName;
if (maskType == PixelMask)
- maskShaderName = MaskFragmentShader;
+ maskShaderName = QGLEngineSharedShaders::MaskFragmentShader;
else if (maskType == SubPixelMask)
- maskShaderName = RgbMaskFragmentShader;
+ maskShaderName = QGLEngineSharedShaders::RgbMaskFragmentShader;
else if (maskType == SubPixelWithGammaMask)
- maskShaderName = RgbMaskWithGammaFragmentShader;
+ maskShaderName = QGLEngineSharedShaders::RgbMaskWithGammaFragmentShader;
else
qCritical("QGLEngineShaderManager::useCorrectShaderProg() - Unknown mask type");
- compileNamedShader(maskShaderName, QGLShader::PartialFragmentShader);
- requiredProgram.maskFragShader = compiledShaders[maskShaderName];
- }
- else
+ requiredProgram.maskFragShader = sharedShaders->compileNamedShader(maskShaderName, QGLShader::PartialFragmentShader);
+ } else {
requiredProgram.maskFragShader = 0;
+ }
if (hasCompose) {
- QGLEngineShaderManager::ShaderName compositionShaderName = QGLEngineShaderManager::InvalidShaderName;
+ QGLEngineSharedShaders::ShaderName compositionShaderName = QGLEngineSharedShaders::InvalidShaderName;
switch (compositionMode) {
case QPainter::CompositionMode_Multiply:
- compositionShaderName = MultiplyCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::MultiplyCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_Screen:
- compositionShaderName = ScreenCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::ScreenCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_Overlay:
- compositionShaderName = OverlayCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::OverlayCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_Darken:
- compositionShaderName = DarkenCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::DarkenCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_Lighten:
- compositionShaderName = LightenCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::LightenCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_ColorDodge:
- compositionShaderName = ColorDodgeCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::ColorDodgeCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_ColorBurn:
- compositionShaderName = ColorBurnCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::ColorBurnCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_HardLight:
- compositionShaderName = HardLightCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::HardLightCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_SoftLight:
- compositionShaderName = SoftLightCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::SoftLightCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_Difference:
- compositionShaderName = DifferenceCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::DifferenceCompositionModeFragmentShader;
break;
case QPainter::CompositionMode_Exclusion:
- compositionShaderName = ExclusionCompositionModeFragmentShader;
+ compositionShaderName = QGLEngineSharedShaders::ExclusionCompositionModeFragmentShader;
break;
default:
qWarning("QGLEngineShaderManager::useCorrectShaderProg() - Unsupported composition mode");
}
- compileNamedShader(compositionShaderName, QGLShader::PartialFragmentShader);
- requiredProgram.compositionFragShader = compiledShaders[compositionShaderName];
- }
- else
+ requiredProgram.compositionFragShader = sharedShaders->compileNamedShader(compositionShaderName, QGLShader::PartialFragmentShader);
+ } 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) {
- if (cachedPrograms[i] == requiredProgram) {
- currentShaderProg = &cachedPrograms[i];
- foundProgramInCache = true;
- break;
- }
}
- // 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()) {
- QLatin1String none("none");
- QLatin1String br("\n");
- QString error;
- error = QLatin1String("Shader program failed to link,")
-#if defined(QT_DEBUG)
- + br
- + QLatin1String(" Shaders Used:\n")
- + QLatin1String(" mainVertexShader = ")
- + (requiredProgram.mainVertexShader ?
- requiredProgram.mainVertexShader->objectName() : none) + br
- + QLatin1String(" positionVertexShader = ")
- + (requiredProgram.positionVertexShader ?
- requiredProgram.positionVertexShader->objectName() : none) + br
- + QLatin1String(" mainFragShader = ")
- + (requiredProgram.mainFragShader ?
- requiredProgram.mainFragShader->objectName() : none) + br
- + QLatin1String(" srcPixelFragShader = ")
- + (requiredProgram.srcPixelFragShader ?
- requiredProgram.srcPixelFragShader->objectName() : none) + br
- + QLatin1String(" maskFragShader = ")
- + (requiredProgram.maskFragShader ?
- requiredProgram.maskFragShader->objectName() : none) + br
- + QLatin1String(" compositionFragShader = ")
- + (requiredProgram.compositionFragShader ?
- requiredProgram.compositionFragShader->objectName() : none) + br
-#endif
- + QLatin1String(" Error Log:\n")
- + QLatin1String(" ") + 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();
- }
- }
+ // At this point, requiredProgram is fully populated so try to find the program in the cache
+ currentShaderProg = sharedShaders->findProgramInCache(requiredProgram);
if (currentShaderProg) {
currentShaderProg->program->enable();
@@ -618,40 +665,4 @@ bool QGLEngineShaderManager::useCorrectShaderProg()
return true;
}
-void QGLEngineShaderManager::compileNamedShader(QGLEngineShaderManager::ShaderName name, QGLShader::ShaderType type)
-{
- if (compiledShaders[name])
- return;
-
- 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
- QMetaEnum m = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("ShaderName"));
- newShader->setObjectName(QLatin1String(m.valueToKey(name)));
-#endif
-
- compiledShaders[name] = newShader;
-}
-
QT_END_NAMESPACE