summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-19 12:33:57 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-03-05 23:51:16 +0000
commit73be2aab75a80a12f85658adab8774b572a24acd (patch)
tree0fab2a03d44660c4367b7d5dcf56eac2a3c9bede /src
parent5ddaadaa7e1f1344b7ebfc479c9893ca36cf32c9 (diff)
Add support for advanced blend equations to our OpenGL QPainter
Mesa and NVidia have been supporting these extensions several years now. It also means we can get rid of the dead unused code we had for advanced compositions. Change-Id: I6a2fcda13490abd977eb4cc3d8b34f186d05ca25 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/gui/opengl/qopenglengineshadermanager.cpp56
-rw-r--r--src/gui/opengl/qopenglengineshadermanager_p.h4
-rw-r--r--src/gui/opengl/qopenglengineshadersource_p.h159
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp23
-rw-r--r--src/gui/opengl/qopenglfunctions.h3
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp69
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp11
7 files changed, 175 insertions, 150 deletions
diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp
index 2f7afa4a66..f66193cb01 100644
--- a/src/gui/opengl/qopenglengineshadermanager.cpp
+++ b/src/gui/opengl/qopenglengineshadermanager.cpp
@@ -153,12 +153,8 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[AffinePositionWithRadialGradientBrushVertexShader] = qopenglslAffinePositionWithRadialGradientBrushVertexShader_core;
code[AffinePositionWithTextureBrushVertexShader] = qopenglslAffinePositionWithTextureBrushVertexShader_core;
- code[MainFragmentShader_CMO] = qopenglslMainFragmentShader_CMO_core;
- code[MainFragmentShader_CM] = qopenglslMainFragmentShader_CM_core;
code[MainFragmentShader_MO] = qopenglslMainFragmentShader_MO_core;
code[MainFragmentShader_M] = qopenglslMainFragmentShader_M_core;
- code[MainFragmentShader_CO] = qopenglslMainFragmentShader_CO_core;
- code[MainFragmentShader_C] = qopenglslMainFragmentShader_C_core;
code[MainFragmentShader_O] = qopenglslMainFragmentShader_O_core;
code[MainFragmentShader] = qopenglslMainFragmentShader_core;
code[MainFragmentShader_ImageArrays] = qopenglslMainFragmentShader_ImageArrays_core;
@@ -203,12 +199,8 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[AffinePositionWithRadialGradientBrushVertexShader] = qopenglslAffinePositionWithRadialGradientBrushVertexShader;
code[AffinePositionWithTextureBrushVertexShader] = qopenglslAffinePositionWithTextureBrushVertexShader;
- code[MainFragmentShader_CMO] = qopenglslMainFragmentShader_CMO;
- code[MainFragmentShader_CM] = qopenglslMainFragmentShader_CM;
code[MainFragmentShader_MO] = qopenglslMainFragmentShader_MO;
code[MainFragmentShader_M] = qopenglslMainFragmentShader_M;
- code[MainFragmentShader_CO] = qopenglslMainFragmentShader_CO;
- code[MainFragmentShader_C] = qopenglslMainFragmentShader_C;
code[MainFragmentShader_O] = qopenglslMainFragmentShader_O;
code[MainFragmentShader] = qopenglslMainFragmentShader;
code[MainFragmentShader_ImageArrays] = qopenglslMainFragmentShader_ImageArrays;
@@ -238,21 +230,20 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[RgbMaskWithGammaFragmentShader] = ""; //###
}
- // These shaders are not implemented yet and therefore are the same
- // for all profiles. Implementations should make a version for both
- // profiles and put the appropriate lines in the if-statement above.
+ // The composition shaders are just layout qualifiers and the same
+ // for all profiles that support them.
code[NoCompositionModeFragmentShader] = "";
- code[MultiplyCompositionModeFragmentShader] = ""; //###
- code[ScreenCompositionModeFragmentShader] = ""; //###
- code[OverlayCompositionModeFragmentShader] = ""; //###
- code[DarkenCompositionModeFragmentShader] = ""; //###
- code[LightenCompositionModeFragmentShader] = ""; //###
- code[ColorDodgeCompositionModeFragmentShader] = ""; //###
- code[ColorBurnCompositionModeFragmentShader] = ""; //###
- code[HardLightCompositionModeFragmentShader] = ""; //###
- code[SoftLightCompositionModeFragmentShader] = ""; //###
- code[DifferenceCompositionModeFragmentShader] = ""; //###
- code[ExclusionCompositionModeFragmentShader] = ""; //###
+ code[MultiplyCompositionModeFragmentShader] = qopenglslMultiplyCompositionModeFragmentShader;
+ code[ScreenCompositionModeFragmentShader] = qopenglslScreenCompositionModeFragmentShader;
+ code[OverlayCompositionModeFragmentShader] = qopenglslOverlayCompositionModeFragmentShader;
+ code[DarkenCompositionModeFragmentShader] = qopenglslDarkenCompositionModeFragmentShader;
+ code[LightenCompositionModeFragmentShader] = qopenglslLightenCompositionModeFragmentShader;
+ code[ColorDodgeCompositionModeFragmentShader] = qopenglslColorDodgeCompositionModeFragmentShader;
+ code[ColorBurnCompositionModeFragmentShader] = qopenglslColorBurnCompositionModeFragmentShader;
+ code[HardLightCompositionModeFragmentShader] = qopenglslHardLightCompositionModeFragmentShader;
+ code[SoftLightCompositionModeFragmentShader] = qopenglslSoftLightCompositionModeFragmentShader;
+ code[DifferenceCompositionModeFragmentShader] = qopenglslDifferenceCompositionModeFragmentShader;
+ code[ExclusionCompositionModeFragmentShader] = qopenglslExclusionCompositionModeFragmentShader;
#if defined(QT_DEBUG)
// Check that all the elements have been filled:
@@ -612,8 +603,11 @@ void QOpenGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mo
if (compositionMode == mode)
return;
+ bool wasAdvanced = compositionMode > QPainter::CompositionMode_Plus;
+ bool isAdvanced = mode > QPainter::CompositionMode_Plus;
+
compositionMode = mode;
- shaderProgNeedsChanging = true; //###
+ shaderProgNeedsChanging = shaderProgNeedsChanging || wasAdvanced || isAdvanced;
}
void QOpenGLEngineShaderManager::setCustomStage(QOpenGLCustomShaderStage* stage)
@@ -783,21 +777,13 @@ bool QOpenGLEngineShaderManager::useCorrectShaderProg()
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_ImageArrays;
} else {
bool useGlobalOpacity = (opacityMode == UniformOpacity);
- if (hasCompose && hasMask && useGlobalOpacity)
- requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CMO;
- if (hasCompose && hasMask && !useGlobalOpacity)
- requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CM;
- if (!hasCompose && hasMask && useGlobalOpacity)
+ if (hasMask && useGlobalOpacity)
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_MO;
- if (!hasCompose && hasMask && !useGlobalOpacity)
+ if (hasMask && !useGlobalOpacity)
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_M;
- if (hasCompose && !hasMask && useGlobalOpacity)
- requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_CO;
- if (hasCompose && !hasMask && !useGlobalOpacity)
- requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_C;
- if (!hasCompose && !hasMask && useGlobalOpacity)
+ if (!hasMask && useGlobalOpacity)
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader_O;
- if (!hasCompose && !hasMask && !useGlobalOpacity)
+ if (!hasMask && !useGlobalOpacity)
requiredProgram.mainFragShader = QOpenGLEngineSharedShaders::MainFragmentShader;
}
diff --git a/src/gui/opengl/qopenglengineshadermanager_p.h b/src/gui/opengl/qopenglengineshadermanager_p.h
index 377501457d..d43788d777 100644
--- a/src/gui/opengl/qopenglengineshadermanager_p.h
+++ b/src/gui/opengl/qopenglengineshadermanager_p.h
@@ -281,12 +281,8 @@ public:
AffinePositionWithTextureBrushVertexShader,
// MainFragmentShader_CMO must be first in the list:
- MainFragmentShader_CMO,
- MainFragmentShader_CM,
MainFragmentShader_MO,
MainFragmentShader_M,
- MainFragmentShader_CO,
- MainFragmentShader_C,
MainFragmentShader_O,
MainFragmentShader,
MainFragmentShader_ImageArrays,
diff --git a/src/gui/opengl/qopenglengineshadersource_p.h b/src/gui/opengl/qopenglengineshadersource_p.h
index a165643839..5d9ee8110b 100644
--- a/src/gui/opengl/qopenglengineshadersource_p.h
+++ b/src/gui/opengl/qopenglengineshadersource_p.h
@@ -403,25 +403,6 @@ static const char* const qopenglslMainFragmentShader_ImageArrays = "\n\
gl_FragColor = srcPixel() * opacity; \n\
}\n";
-static const char* const qopenglslMainFragmentShader_CMO = "\n\
- uniform lowp float globalOpacity; \n\
- lowp vec4 srcPixel(); \n\
- lowp vec4 applyMask(lowp vec4); \n\
- lowp vec4 compose(lowp vec4); \n\
- void main() \n\
- { \n\
- gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\
- }\n";
-
-static const char* const qopenglslMainFragmentShader_CM = "\n\
- lowp vec4 srcPixel(); \n\
- lowp vec4 applyMask(lowp vec4); \n\
- lowp vec4 compose(lowp vec4); \n\
- void main() \n\
- { \n\
- gl_FragColor = applyMask(compose(srcPixel())); \n\
- }\n";
-
static const char* const qopenglslMainFragmentShader_MO = "\n\
uniform lowp float globalOpacity; \n\
lowp vec4 srcPixel(); \n\
@@ -439,23 +420,6 @@ static const char* const qopenglslMainFragmentShader_M = "\n\
gl_FragColor = applyMask(srcPixel()); \n\
}\n";
-static const char* const qopenglslMainFragmentShader_CO = "\n\
- uniform lowp float globalOpacity; \n\
- lowp vec4 srcPixel(); \n\
- lowp vec4 compose(lowp vec4); \n\
- void main() \n\
- { \n\
- gl_FragColor = compose(srcPixel()*globalOpacity); \n\
- }\n";
-
-static const char* const qopenglslMainFragmentShader_C = "\n\
- lowp vec4 srcPixel(); \n\
- lowp vec4 compose(lowp vec4); \n\
- void main() \n\
- { \n\
- gl_FragColor = compose(srcPixel()); \n\
- }\n";
-
static const char* const qopenglslMainFragmentShader_O = "\n\
uniform lowp float globalOpacity; \n\
lowp vec4 srcPixel(); \n\
@@ -513,22 +477,65 @@ static const char* const qopenglslRgbMaskFragmentShaderPass2 = "\n\
return src * mask; \n\
}\n";
+static const char* const qopenglslMultiplyCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_multiply) out;\n\
+ #endif\n";
+
+static const char* const qopenglslScreenCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_screen) out;\n\
+ #endif\n";
+
+static const char* const qopenglslOverlayCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_overlay) out;\n\
+ #endif\n";
+
+static const char* const qopenglslDarkenCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_darken) out;\n\
+ #endif\n";
+
+static const char* const qopenglslLightenCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_lighten) out;\n\
+ #endif\n";
+
+static const char* const qopenglslColorDodgeCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_colordodge) out;\n\
+ #endif\n";
+
+static const char* const qopenglslColorBurnCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_colorburn) out;\n\
+ #endif\n";
+
+static const char* const qopenglslHardLightCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_hardlight) out;\n\
+ #endif\n";
+
+static const char* const qopenglslSoftLightCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_softlight) out;\n\
+ #endif\n";
+
+static const char* const qopenglslDifferenceCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_difference) out;\n\
+ #endif\n";
+
+static const char* const qopenglslExclusionCompositionModeFragmentShader = "\n\
+ #ifdef GL_KHR_blend_equation_advanced\n\
+ layout(blend_support_exclusion) out;\n\
+ #endif\n";
+
/*
Left to implement:
RgbMaskFragmentShader,
RgbMaskWithGammaFragmentShader,
-
- MultiplyCompositionModeFragmentShader,
- ScreenCompositionModeFragmentShader,
- OverlayCompositionModeFragmentShader,
- DarkenCompositionModeFragmentShader,
- LightenCompositionModeFragmentShader,
- ColorDodgeCompositionModeFragmentShader,
- ColorBurnCompositionModeFragmentShader,
- HardLightCompositionModeFragmentShader,
- SoftLightCompositionModeFragmentShader,
- DifferenceCompositionModeFragmentShader,
- ExclusionCompositionModeFragmentShader,
*/
/*
@@ -880,29 +887,6 @@ static const char* const qopenglslMainFragmentShader_ImageArrays_core =
fragColor = srcPixel() * opacity; \n\
}\n";
-static const char* const qopenglslMainFragmentShader_CMO_core =
- "#version 150 core\n\
- out vec4 fragColor; \n\
- uniform float globalOpacity; \n\
- vec4 srcPixel(); \n\
- vec4 applyMask(vec4); \n\
- vec4 compose(vec4); \n\
- void main() \n\
- { \n\
- fragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\
- }\n";
-
-static const char* const qopenglslMainFragmentShader_CM_core =
- "#version 150 core\n\
- out vec4 fragColor; \n\
- vec4 srcPixel(); \n\
- vec4 applyMask(vec4); \n\
- vec4 compose(vec4); \n\
- void main() \n\
- { \n\
- fragColor = applyMask(compose(srcPixel())); \n\
- }\n";
-
static const char* const qopenglslMainFragmentShader_MO_core =
"#version 150 core\n\
out vec4 fragColor; \n\
@@ -924,27 +908,6 @@ static const char* const qopenglslMainFragmentShader_M_core =
fragColor = applyMask(srcPixel()); \n\
}\n";
-static const char* const qopenglslMainFragmentShader_CO_core =
- "#version 150 core\n\
- out vec4 fragColor; \n\
- uniform float globalOpacity; \n\
- vec4 srcPixel(); \n\
- vec4 compose(vec4); \n\
- void main() \n\
- { \n\
- fragColor = compose(srcPixel()*globalOpacity); \n\
- }\n";
-
-static const char* const qopenglslMainFragmentShader_C_core =
- "#version 150 core\n\
- out vec4 fragColor; \n\
- vec4 srcPixel(); \n\
- vec4 compose(vec4); \n\
- void main() \n\
- { \n\
- fragColor = compose(srcPixel()); \n\
- }\n";
-
static const char* const qopenglslMainFragmentShader_O_core =
"#version 150 core\n\
out vec4 fragColor; \n\
@@ -1010,18 +973,6 @@ static const char* const qopenglslRgbMaskFragmentShaderPass2_core = "\n\
Left to implement:
RgbMaskFragmentShader_core,
RgbMaskWithGammaFragmentShader_core,
-
- MultiplyCompositionModeFragmentShader_core,
- ScreenCompositionModeFragmentShader_core,
- OverlayCompositionModeFragmentShader_core,
- DarkenCompositionModeFragmentShader_core,
- LightenCompositionModeFragmentShader_core,
- ColorDodgeCompositionModeFragmentShader_core,
- ColorBurnCompositionModeFragmentShader_core,
- HardLightCompositionModeFragmentShader_core,
- SoftLightCompositionModeFragmentShader_core,
- DifferenceCompositionModeFragmentShader_core,
- ExclusionCompositionModeFragmentShader_core,
*/
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index ff044a91da..236c81ac93 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -294,9 +294,19 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context)
static int qt_gl_resolve_features()
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLExtensionMatcher extensions;
+ int features = 0;
+ if ((extensions.match("GL_KHR_blend_equation_advanced")
+ || extensions.match("GL_NV_blend_equation_advanced")) &&
+ (extensions.match("GL_KHR_blend_equation_advanced_coherent")
+ || extensions.match("GL_NV_blend_equation_advanced_coherent"))) {
+ // We need both the advanced equations and the coherency for us
+ // to be able to easily use the new blend equations
+ features |= QOpenGLFunctions::BlendEquationAdvanced;
+ }
if (ctx->isOpenGLES()) {
// OpenGL ES
- int features = QOpenGLFunctions::Multitexture |
+ features |= QOpenGLFunctions::Multitexture |
QOpenGLFunctions::Shaders |
QOpenGLFunctions::Buffers |
QOpenGLFunctions::Framebuffers |
@@ -308,7 +318,6 @@ static int qt_gl_resolve_features()
QOpenGLFunctions::CompressedTextures |
QOpenGLFunctions::Multisample |
QOpenGLFunctions::StencilSeparate;
- QOpenGLExtensionMatcher extensions;
if (extensions.match("GL_IMG_texture_npot"))
features |= QOpenGLFunctions::NPOTTextures;
if (extensions.match("GL_OES_texture_npot"))
@@ -320,14 +329,18 @@ static int qt_gl_resolve_features()
if (!(renderer && strstr(renderer, "Mesa")))
features |= QOpenGLFunctions::TextureRGFormats;
}
- if (ctx->format().majorVersion() >= 3)
+ if (ctx->format().majorVersion() >= 3) {
features |= QOpenGLFunctions::MultipleRenderTargets;
+ if (ctx->format().minorVersion() >= 2 && extensions.match("GL_KHR_blend_equation_advanced_coherent")) {
+ // GL_KHR_blend_equation_advanced is included in OpenGL ES/3.2
+ features |= QOpenGLFunctions::BlendEquationAdvanced;
+ }
+ }
return features;
} else {
// OpenGL
- int features = QOpenGLFunctions::TextureRGFormats;
+ features |= QOpenGLFunctions::TextureRGFormats;
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
- QOpenGLExtensionMatcher extensions;
if (format.majorVersion() >= 3)
features |= QOpenGLFunctions::Framebuffers | QOpenGLFunctions::MultipleRenderTargets;
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
index 1a43f13d9b..00287b0665 100644
--- a/src/gui/opengl/qopenglfunctions.h
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -277,7 +277,8 @@ public:
NPOTTextureRepeat = 0x2000,
FixedFunctionPipeline = 0x4000,
TextureRGFormats = 0x8000,
- MultipleRenderTargets = 0x10000
+ MultipleRenderTargets = 0x10000,
+ BlendEquationAdvanced = 0x20000,
};
Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature)
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index 17dc9df619..fb7e6fce97 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -87,8 +87,27 @@
#include <QDebug>
-QT_BEGIN_NAMESPACE
+#ifndef GL_KHR_blend_equation_advanced
+#define GL_KHR_blend_equation_advanced 1
+#define GL_MULTIPLY_KHR 0x9294
+#define GL_SCREEN_KHR 0x9295
+#define GL_OVERLAY_KHR 0x9296
+#define GL_DARKEN_KHR 0x9297
+#define GL_LIGHTEN_KHR 0x9298
+#define GL_COLORDODGE_KHR 0x9299
+#define GL_COLORBURN_KHR 0x929A
+#define GL_HARDLIGHT_KHR 0x929B
+#define GL_SOFTLIGHT_KHR 0x929C
+#define GL_DIFFERENCE_KHR 0x929E
+#define GL_EXCLUSION_KHR 0x92A0
+#endif /* GL_KHR_blend_equation_advanced */
+
+#ifndef GL_KHR_blend_equation_advanced_coherent
+#define GL_KHR_blend_equation_advanced_coherent 1
+#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285
+#endif /* GL_KHR_blend_equation_advanced_coherent */
+QT_BEGIN_NAMESPACE
Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
@@ -498,6 +517,21 @@ void QOpenGL2PaintEngineExPrivate::updateCompositionMode()
// NOTE: The entire paint engine works on pre-multiplied data - which is why some of these
// composition modes look odd.
// qDebug() << "QOpenGL2PaintEngineExPrivate::updateCompositionMode() - Setting GL composition mode for " << q->state()->composition_mode;
+ if (ctx->functions()->hasOpenGLFeature(QOpenGLFunctions::BlendEquationAdvanced)) {
+ if (q->state()->composition_mode <= QPainter::CompositionMode_Plus) {
+ funcs.glDisable(GL_BLEND_ADVANCED_COHERENT_KHR);
+ funcs.glBlendEquation(GL_FUNC_ADD);
+ } else {
+ funcs.glEnable(GL_BLEND_ADVANCED_COHERENT_KHR);
+ }
+ shaderManager->setCompositionMode(q->state()->composition_mode);
+ } else {
+ if (q->state()->composition_mode > QPainter::CompositionMode_Plus) {
+ qWarning("Unsupported composition mode");
+ compositionModeDirty = false;
+ return;
+ }
+ }
switch(q->state()->composition_mode) {
case QPainter::CompositionMode_SourceOver:
funcs.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -538,6 +572,39 @@ void QOpenGL2PaintEngineExPrivate::updateCompositionMode()
case QPainter::CompositionMode_Plus:
funcs.glBlendFunc(GL_ONE, GL_ONE);
break;
+ case QPainter::CompositionMode_Multiply:
+ funcs.glBlendEquation(GL_MULTIPLY_KHR);
+ break;
+ case QPainter::CompositionMode_Screen:
+ funcs.glBlendEquation(GL_SCREEN_KHR);
+ break;
+ case QPainter::CompositionMode_Overlay:
+ funcs.glBlendEquation(GL_OVERLAY_KHR);
+ break;
+ case QPainter::CompositionMode_Darken:
+ funcs.glBlendEquation(GL_DARKEN_KHR);
+ break;
+ case QPainter::CompositionMode_Lighten:
+ funcs.glBlendEquation(GL_LIGHTEN_KHR);
+ break;
+ case QPainter::CompositionMode_ColorDodge:
+ funcs.glBlendEquation(GL_COLORDODGE_KHR);
+ break;
+ case QPainter::CompositionMode_ColorBurn:
+ funcs.glBlendEquation(GL_COLORBURN_KHR);
+ break;
+ case QPainter::CompositionMode_HardLight:
+ funcs.glBlendEquation(GL_HARDLIGHT_KHR);
+ break;
+ case QPainter::CompositionMode_SoftLight:
+ funcs.glBlendEquation(GL_SOFTLIGHT_KHR);
+ break;
+ case QPainter::CompositionMode_Difference:
+ funcs.glBlendEquation(GL_DIFFERENCE_KHR);
+ break;
+ case QPainter::CompositionMode_Exclusion:
+ funcs.glBlendEquation(GL_EXCLUSION_KHR);
+ break;
default:
qWarning("Unsupported composition mode");
break;
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index 1fe30f7e0e..46963f0dbf 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -497,6 +497,13 @@ static const char redefineHighp[] =
"#endif\n";
#endif
+// Boiler-plate header to have the layout attributes available we need later
+static const char blendEquationAdvancedHeader[] =
+ "#ifdef GL_KHR_blend_equation_advanced\n"
+ "#extension GL_ARB_fragment_coord_conventions : enable\n"
+ "#extension GL_KHR_blend_equation_advanced : enable\n"
+ "#endif\n";
+
struct QVersionDirectivePosition
{
Q_DECL_CONSTEXPR QVersionDirectivePosition(int position = 0, int line = -1)
@@ -637,6 +644,10 @@ bool QOpenGLShader::compileSourceCode(const char *source)
}
}
}
+ if (d->shaderType == Fragment) {
+ sourceChunks.append(blendEquationAdvancedHeader);
+ sourceChunkLengths.append(GLint(sizeof(blendEquationAdvancedHeader) - 1));
+ }
// The precision qualifiers are useful on OpenGL/ES systems,
// but usually not present on desktop systems.