aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/quick/shared/shared.h6
-rw-r--r--src/particles/particles.pri7
-rw-r--r--src/particles/particles.qrc5
-rw-r--r--src/particles/qquickimageparticle.cpp87
-rw-r--r--src/particles/shaders/customparticle.frag2
-rw-r--r--src/particles/shaders/customparticle_core.frag13
-rw-r--r--src/particles/shaders/customparticle_core.vert4
-rw-r--r--src/particles/shaders/customparticletemplate.vert2
-rw-r--r--src/particles/shaders/customparticletemplate_core.vert28
-rw-r--r--src/particles/shaders/imageparticle.frag2
-rw-r--r--src/particles/shaders/imageparticle.vert2
-rw-r--r--src/particles/shaders/imageparticle_core.frag44
-rw-r--r--src/particles/shaders/imageparticle_core.vert145
-rw-r--r--src/quick/items/items.pri8
-rw-r--r--src/quick/items/items.qrc6
-rw-r--r--src/quick/items/shaders/shadereffect_core.frag13
-rw-r--r--src/quick/items/shaders/shadereffect_core.vert14
-rw-r--r--src/quick/items/shaders/shadereffectfallback_core.frag8
-rw-r--r--src/quick/items/shaders/shadereffectfallback_core.vert10
-rw-r--r--src/quick/items/shaders/sprite_core.frag16
-rw-r--r--src/quick/items/shaders/sprite_core.vert24
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp29
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h6
-rw-r--r--src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp29
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp4
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h6
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp3
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp84
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h9
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp4
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h1
-rw-r--r--src/quick/scenegraph/scenegraph.pri34
-rw-r--r--src/quick/scenegraph/scenegraph.qrc32
-rw-r--r--src/quick/scenegraph/shaders/24bittextmask.frag4
-rw-r--r--src/quick/scenegraph/shaders/24bittextmask_core.frag14
-rw-r--r--src/quick/scenegraph/shaders/8bittextmask.frag4
-rw-r--r--src/quick/scenegraph/shaders/8bittextmask_core.frag13
-rw-r--r--src/quick/scenegraph/shaders/distancefieldoutlinetext_core.frag20
-rw-r--r--src/quick/scenegraph/shaders/distancefieldshiftedtext_core.frag20
-rw-r--r--src/quick/scenegraph/shaders/distancefieldshiftedtext_core.vert18
-rw-r--r--src/quick/scenegraph/shaders/distancefieldtext_core.frag16
-rw-r--r--src/quick/scenegraph/shaders/distancefieldtext_core.vert15
-rw-r--r--src/quick/scenegraph/shaders/flatcolor_core.frag10
-rw-r--r--src/quick/scenegraph/shaders/flatcolor_core.vert10
-rw-r--r--src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext_core.frag32
-rw-r--r--src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext_core.vert36
-rw-r--r--src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext_core.frag21
-rw-r--r--src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext_core.vert29
-rw-r--r--src/quick/scenegraph/shaders/opaquetexture_core.frag12
-rw-r--r--src/quick/scenegraph/shaders/opaquetexture_core.vert14
-rw-r--r--src/quick/scenegraph/shaders/outlinedtext_core.frag25
-rw-r--r--src/quick/scenegraph/shaders/outlinedtext_core.vert24
-rw-r--r--src/quick/scenegraph/shaders/rendernode_core.frag12
-rw-r--r--src/quick/scenegraph/shaders/rendernode_core.vert12
-rw-r--r--src/quick/scenegraph/shaders/smoothcolor_core.frag10
-rw-r--r--src/quick/scenegraph/shaders/smoothcolor_core.vert47
-rw-r--r--src/quick/scenegraph/shaders/smoothtexture_core.frag13
-rw-r--r--src/quick/scenegraph/shaders/smoothtexture_core.vert54
-rw-r--r--src/quick/scenegraph/shaders/stencilclip_core.frag8
-rw-r--r--src/quick/scenegraph/shaders/stencilclip_core.vert10
-rw-r--r--src/quick/scenegraph/shaders/styledtext_core.frag18
-rw-r--r--src/quick/scenegraph/shaders/styledtext_core.vert18
-rw-r--r--src/quick/scenegraph/shaders/textmask_core.frag14
-rw-r--r--src/quick/scenegraph/shaders/textmask_core.vert15
-rw-r--r--src/quick/scenegraph/shaders/texture_core.frag13
-rw-r--r--src/quick/scenegraph/shaders/vertexcolor_core.frag10
-rw-r--r--src/quick/scenegraph/shaders/vertexcolor_core.vert15
-rw-r--r--src/quick/scenegraph/util/qsgshadersourcebuilder.cpp307
-rw-r--r--src/quick/scenegraph/util/qsgshadersourcebuilder_p.h5
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp11
70 files changed, 1551 insertions, 65 deletions
diff --git a/examples/quick/shared/shared.h b/examples/quick/shared/shared.h
index 1376459ae7..d2f7c98311 100644
--- a/examples/quick/shared/shared.h
+++ b/examples/quick/shared/shared.h
@@ -49,6 +49,12 @@
app.setOrganizationDomain("qt-project.org");\
app.setApplicationName(QFileInfo(app.applicationFilePath()).baseName());\
QQuickView view;\
+ if (qgetenv("QT_QUICK_CORE_PROFILE").toInt()) {\
+ QSurfaceFormat f = view.format();\
+ f.setProfile(QSurfaceFormat::CoreProfile);\
+ f.setVersion(4, 4);\
+ view.setFormat(f);\
+ }\
view.connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit()));\
new QQmlFileSelector(view.engine(), &view);\
view.setSource(QUrl("qrc:///" #NAME ".qml")); \
diff --git a/src/particles/particles.pri b/src/particles/particles.pri
index b391050a58..af71634ec6 100644
--- a/src/particles/particles.pri
+++ b/src/particles/particles.pri
@@ -68,7 +68,12 @@ OTHER_FILES += \
$$PWD/shaders/customparticle.vert \
$$PWD/shaders/customparticle.frag \
$$PWD/shaders/imageparticle.vert \
- $$PWD/shaders/imageparticle.frag
+ $$PWD/shaders/imageparticle.frag \
+ $$PWD/shaders/customparticletemplate_core.vert \
+ $$PWD/shaders/customparticle_core.vert \
+ $$PWD/shaders/customparticle_core.frag \
+ $$PWD/shaders/imageparticle_core.vert \
+ $$PWD/shaders/imageparticle_core.frag
RESOURCES += \
$$PWD/particles.qrc
diff --git a/src/particles/particles.qrc b/src/particles/particles.qrc
index 689a5fb4e9..ad44cf406e 100644
--- a/src/particles/particles.qrc
+++ b/src/particles/particles.qrc
@@ -11,5 +11,10 @@
<file>shaders/customparticletemplate.vert</file>
<file>shaders/imageparticle.frag</file>
<file>shaders/imageparticle.vert</file>
+ <file>shaders/customparticle_core.frag</file>
+ <file>shaders/customparticle_core.vert</file>
+ <file>shaders/customparticletemplate_core.vert</file>
+ <file>shaders/imageparticle_core.frag</file>
+ <file>shaders/imageparticle_core.vert</file>
</qresource>
</RCC>
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index dfe4524c7c..0bea3a87af 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -59,14 +59,8 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_OPENGL_ES_2
-#define SHADER_DEFINES "#version 120\n"
-#else
-#define SHADER_DEFINES ""
-#endif
-
#if defined(Q_OS_BLACKBERRY)
-#define SHADER_PLATFORM_DEFINES "#define Q_OS_BLACKBERRY\n"
+#define SHADER_PLATFORM_DEFINES "Q_OS_BLACKBERRY\n"
#else
#define SHADER_PLATFORM_DEFINES
#endif
@@ -107,15 +101,26 @@ public:
{
QSGShaderSourceBuilder builder;
- builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
- builder.appendSource(QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n"));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+ builder.addDefinition(QByteArrayLiteral("TABLE"));
+ builder.addDefinition(QByteArrayLiteral("DEFORM"));
+ builder.addDefinition(QByteArrayLiteral("COLOR"));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
+
m_vertex_code = builder.source();
builder.clear();
- builder.appendSource(QByteArray(SHADER_DEFINES));
- builder.appendSource(QByteArray("#define TABLE\n#define DEFORM\n#define COLOR\n"));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+ builder.addDefinition(QByteArrayLiteral("TABLE"));
+ builder.addDefinition(QByteArrayLiteral("DEFORM"));
+ builder.addDefinition(QByteArrayLiteral("COLOR"));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
m_fragment_code = builder.source();
Q_ASSERT(!m_vertex_code.isNull());
@@ -174,15 +179,23 @@ public:
{
QSGShaderSourceBuilder builder;
- builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
- builder.appendSource(QByteArray("#define DEFORM\n#define COLOR\n"));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+ builder.addDefinition(QByteArrayLiteral("DEFORM"));
+ builder.addDefinition(QByteArrayLiteral("COLOR"));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
m_vertex_code = builder.source();
builder.clear();
- builder.appendSource(QByteArray(SHADER_DEFINES));
- builder.appendSource(QByteArray("#define DEFORM\n#define COLOR\n"));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+ builder.addDefinition(QByteArrayLiteral("DEFORM"));
+ builder.addDefinition(QByteArrayLiteral("COLOR"));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
m_fragment_code = builder.source();
Q_ASSERT(!m_vertex_code.isNull());
@@ -230,15 +243,27 @@ public:
{
QSGShaderSourceBuilder builder;
- builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
- builder.appendSource(QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n"));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+ builder.addDefinition(QByteArrayLiteral("SPRITE"));
+ builder.addDefinition(QByteArrayLiteral("TABLE"));
+ builder.addDefinition(QByteArrayLiteral("DEFORM"));
+ builder.addDefinition(QByteArrayLiteral("COLOR"));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
m_vertex_code = builder.source();
builder.clear();
- builder.appendSource(QByteArray(SHADER_DEFINES));
- builder.appendSource(QByteArray("#define SPRITE\n#define TABLE\n#define DEFORM\n#define COLOR\n"));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+ builder.addDefinition(QByteArrayLiteral("SPRITE"));
+ builder.addDefinition(QByteArrayLiteral("TABLE"));
+ builder.addDefinition(QByteArrayLiteral("DEFORM"));
+ builder.addDefinition(QByteArrayLiteral("COLOR"));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
m_fragment_code = builder.source();
Q_ASSERT(!m_vertex_code.isNull());
@@ -299,15 +324,21 @@ public:
{
QSGShaderSourceBuilder builder;
- builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
- builder.appendSource(QByteArray("#define COLOR\n"));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+ builder.addDefinition(QByteArrayLiteral("COLOR"));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
m_vertex_code = builder.source();
builder.clear();
- builder.appendSource(QByteArray(SHADER_DEFINES));
- builder.appendSource(QByteArray("#define COLOR\n"));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+ builder.addDefinition(QByteArrayLiteral("COLOR"));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
m_fragment_code = builder.source();
Q_ASSERT(!m_vertex_code.isNull());
@@ -370,13 +401,19 @@ public:
{
QSGShaderSourceBuilder builder;
- builder.appendSource(QByteArray(SHADER_DEFINES) + QByteArray(SHADER_PLATFORM_DEFINES));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.vert"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
m_vertex_code = builder.source();
builder.clear();
- builder.appendSource(QByteArray(SHADER_DEFINES));
builder.appendSourceFile(QStringLiteral(":/particles/shaders/imageparticle.frag"));
+ builder.addDefinition(QByteArray(SHADER_PLATFORM_DEFINES));
+#if defined(QT_OPENGL_ES_2)
+ builder.removeVersion();
+#endif
m_fragment_code = builder.source();
Q_ASSERT(!m_vertex_code.isNull());
diff --git a/src/particles/shaders/customparticle.frag b/src/particles/shaders/customparticle.frag
index c1c15ecb0c..64007029f7 100644
--- a/src/particles/shaders/customparticle.frag
+++ b/src/particles/shaders/customparticle.frag
@@ -1,3 +1,5 @@
+#version 120
+
varying highp vec2 qt_TexCoord0;
uniform sampler2D source;
diff --git a/src/particles/shaders/customparticle_core.frag b/src/particles/shaders/customparticle_core.frag
new file mode 100644
index 0000000000..699c834605
--- /dev/null
+++ b/src/particles/shaders/customparticle_core.frag
@@ -0,0 +1,13 @@
+#version 150
+
+in vec2 qt_TexCoord0;
+
+out vec4 fragColor;
+
+uniform sampler2D source;
+uniform float qt_Opacity;
+
+void main()
+{
+ fragColor = texture(source, qt_TexCoord0) * qt_Opacity;
+} \ No newline at end of file
diff --git a/src/particles/shaders/customparticle_core.vert b/src/particles/shaders/customparticle_core.vert
new file mode 100644
index 0000000000..b99f73ea53
--- /dev/null
+++ b/src/particles/shaders/customparticle_core.vert
@@ -0,0 +1,4 @@
+void main()
+{
+ defaultMain();
+} \ No newline at end of file
diff --git a/src/particles/shaders/customparticletemplate.vert b/src/particles/shaders/customparticletemplate.vert
index c482c4207b..eef8458a85 100644
--- a/src/particles/shaders/customparticletemplate.vert
+++ b/src/particles/shaders/customparticletemplate.vert
@@ -1,3 +1,5 @@
+#version 120
+
attribute highp vec2 qt_ParticlePos;
attribute highp vec2 qt_ParticleTex;
attribute highp vec4 qt_ParticleData; // x = time, y = lifeSpan, z = size, w = endSize
diff --git a/src/particles/shaders/customparticletemplate_core.vert b/src/particles/shaders/customparticletemplate_core.vert
new file mode 100644
index 0000000000..15d38e797c
--- /dev/null
+++ b/src/particles/shaders/customparticletemplate_core.vert
@@ -0,0 +1,28 @@
+#version 150 core
+
+in vec2 qt_ParticlePos;
+in vec2 qt_ParticleTex;
+in vec4 qt_ParticleData; // x = time, y = lifeSpan, z = size, w = endSize
+in vec4 qt_ParticleVec; // x,y = constant velocity, z,w = acceleration
+in float qt_ParticleR;
+
+out vec2 qt_TexCoord0;
+
+uniform mat4 qt_Matrix;
+uniform float qt_Timestamp;
+
+void defaultMain()
+{
+ qt_TexCoord0 = qt_ParticleTex;
+ float size = qt_ParticleData.z;
+ float endSize = qt_ParticleData.w;
+ float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y;
+ float currentSize = mix(size, endSize, t * t);
+ if (t < 0. || t > 1.)
+ currentSize = 0.;
+ vec2 pos = qt_ParticlePos
+ - currentSize / 2. + currentSize * qt_ParticleTex // adjust size
+ + qt_ParticleVec.xy * t * qt_ParticleData.y // apply velocity vector..
+ + 0.5 * qt_ParticleVec.zw * pow(t * qt_ParticleData.y, 2.);
+ gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
+}
diff --git a/src/particles/shaders/imageparticle.frag b/src/particles/shaders/imageparticle.frag
index 699b90babf..92795a5381 100644
--- a/src/particles/shaders/imageparticle.frag
+++ b/src/particles/shaders/imageparticle.frag
@@ -1,3 +1,5 @@
+#version 120
+
uniform sampler2D _qt_texture;
uniform lowp float qt_Opacity;
diff --git a/src/particles/shaders/imageparticle.vert b/src/particles/shaders/imageparticle.vert
index 9e607a7477..377f831686 100644
--- a/src/particles/shaders/imageparticle.vert
+++ b/src/particles/shaders/imageparticle.vert
@@ -1,3 +1,5 @@
+#version 120
+
#if defined(DEFORM)
attribute highp vec4 vPosTex;
#else
diff --git a/src/particles/shaders/imageparticle_core.frag b/src/particles/shaders/imageparticle_core.frag
new file mode 100644
index 0000000000..3ac8c8d34e
--- /dev/null
+++ b/src/particles/shaders/imageparticle_core.frag
@@ -0,0 +1,44 @@
+#version 150 core
+
+#if defined(SPRITE)
+in vec4 fTexS;
+#elif defined(DEFORM)
+in vec2 fTex;
+#endif
+
+#if defined(COLOR)
+in vec4 fColor;
+#else
+in float fFade;
+#endif
+
+#if defined(TABLE)
+in vec2 tt;
+uniform sampler2D colortable;
+#endif
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform float qt_Opacity;
+
+void main()
+{
+#if defined(SPRITE)
+ fragColor = mix(texture(_qt_texture, fTexS.xy), texture(_qt_texture, fTexS.zw), tt.y)
+ * fColor
+ * texture(colortable, tt)
+ * qt_Opacity;
+#elif defined(TABLE)
+ fragColor = texture(_qt_texture, fTex)
+ * fColor
+ * texture(colortable, tt)
+ * qt_Opacity;
+#elif defined(DEFORM)
+ fragColor = texture(_qt_texture, fTex) * fColor * qt_Opacity;
+#elif defined(COLOR)
+ fragColor = texture(_qt_texture, gl_PointCoord) * fColor * qt_Opacity;
+#else
+ fragColor = texture(_qt_texture, gl_PointCoord) * fFade * qt_Opacity;
+#endif
+} \ No newline at end of file
diff --git a/src/particles/shaders/imageparticle_core.vert b/src/particles/shaders/imageparticle_core.vert
new file mode 100644
index 0000000000..ed9a918eb3
--- /dev/null
+++ b/src/particles/shaders/imageparticle_core.vert
@@ -0,0 +1,145 @@
+#version 150 core
+
+#if defined(DEFORM)
+in vec4 vPosTex;
+#else
+in vec2 vPos;
+#endif
+
+in vec4 vData; // x = time, y = lifeSpan, z = size, w = endSize
+in vec4 vVec; // x,y = constant velocity, z,w = acceleration
+uniform float entry;
+
+#if defined(COLOR)
+in vec4 vColor;
+#endif
+
+#if defined(DEFORM)
+in vec4 vDeformVec; // x,y x unit vector; z,w = y unit vector
+in vec3 vRotation; // x = radians of rotation, y = rotation velocity, z = bool autoRotate
+#endif
+
+#if defined(SPRITE)
+in vec3 vAnimData; // w,h(premultiplied of anim), interpolation progress
+in vec4 vAnimPos; // x,y, x,y (two frames for interpolation)
+#endif
+
+uniform mat4 qt_Matrix;
+uniform float timestamp;
+
+#if defined(TABLE)
+out vec2 tt;//y is progress if Sprite mode
+uniform float sizetable[64];
+uniform float opacitytable[64];
+#endif
+
+#if defined(SPRITE)
+out vec4 fTexS;
+#elif defined(DEFORM)
+out vec2 fTex;
+#endif
+
+#if defined(COLOR)
+out vec4 fColor;
+#else
+out float fFade;
+#endif
+
+
+void main()
+{
+ float t = (timestamp - vData.x) / vData.y;
+ if (t < 0. || t > 1.) {
+#if defined(DEFORM)
+ gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);
+#else
+ gl_PointSize = 0.;
+#endif
+ } else {
+#if defined(SPRITE)
+ tt.y = vAnimData.z;
+
+ // Calculate frame location in texture
+ fTexS.xy = vAnimPos.xy + vPosTex.zw * vAnimData.xy;
+
+ // Next frame is also passed, for interpolation
+ fTexS.zw = vAnimPos.zw + vPosTex.zw * vAnimData.xy;
+
+#elif defined(DEFORM)
+ fTex = vPosTex.zw;
+#endif
+ float currentSize = mix(vData.z, vData.w, t * t);
+#if defined (Q_OS_BLACKBERRY)
+ float fade = 1.;
+#else
+ float fade = 1.;
+#endif
+ float fadeIn = min(t * 10., 1.);
+ float fadeOut = 1. - clamp((t - 0.75) * 4.,0., 1.);
+
+#if defined(TABLE)
+ currentSize = currentSize * sizetable[int(floor(t*64.))];
+ fade = fade * opacitytable[int(floor(t*64.))];
+#endif
+
+ if (entry == 1.)
+ fade = fade * fadeIn * fadeOut;
+ else if (entry == 2.)
+ currentSize = currentSize * fadeIn * fadeOut;
+
+ if (currentSize <= 0.) {
+#if defined(DEFORM)
+ gl_Position = qt_Matrix * vec4(vPosTex.x, vPosTex.y, 0., 1.);
+#else
+ gl_PointSize = 0.;
+#endif
+ } else {
+ if (currentSize < 3.) // Sizes too small look jittery as they move
+ currentSize = 3.;
+
+ vec2 pos;
+#if defined(DEFORM)
+ float rotation = vRotation.x + vRotation.y * t * vData.y;
+ if (vRotation.z == 1.0) {
+ vec2 curVel = vVec.zw * t * vData.y + vVec.xy;
+ if (length(curVel) > 0.)
+ rotation += atan(curVel.y, curVel.x);
+ }
+ vec2 trigCalcs = vec2(cos(rotation), sin(rotation));
+ vec4 deform = vDeformVec * currentSize * (vPosTex.zzww - 0.5);
+ vec4 rotatedDeform = deform.xxzz * trigCalcs.xyxy;
+ rotatedDeform = rotatedDeform + (deform.yyww * trigCalcs.yxyx * vec4(-1.,1.,-1.,1.));
+ /* The readable version:
+ vec2 xDeform = vDeformVec.xy * currentSize * (vTex.x-0.5);
+ vec2 yDeform = vDeformVec.zw * currentSize * (vTex.y-0.5);
+ vec2 xRotatedDeform;
+ xRotatedDeform.x = trigCalcs.x*xDeform.x - trigCalcs.y*xDeform.y;
+ xRotatedDeform.y = trigCalcs.y*xDeform.x + trigCalcs.x*xDeform.y;
+ vec2 yRotatedDeform;
+ yRotatedDeform.x = trigCalcs.x*yDeform.x - trigCalcs.y*yDeform.y;
+ yRotatedDeform.y = trigCalcs.y*yDeform.x + trigCalcs.x*yDeform.y;
+ */
+ pos = vPosTex.xy
+ + rotatedDeform.xy
+ + rotatedDeform.zw
+ + vVec.xy * t * vData.y // apply velocity
+ + 0.5 * vVec.zw * pow(t * vData.y, 2.); // apply acceleration
+#else
+ pos = vPos
+ + vVec.xy * t * vData.y // apply velocity vector..
+ + 0.5 * vVec.zw * pow(t * vData.y, 2.);
+ gl_PointSize = currentSize;
+#endif
+ gl_Position = qt_Matrix * vec4(pos.x, pos.y, 0, 1);
+
+#if defined(COLOR)
+ fColor = vColor * fade;
+#else
+ fFade = fade;
+#endif
+#if defined(TABLE)
+ tt.x = t;
+#endif
+ }
+ }
+} \ No newline at end of file
diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri
index d0ebbcfcdb..3996512f9d 100644
--- a/src/quick/items/items.pri
+++ b/src/quick/items/items.pri
@@ -145,7 +145,13 @@ OTHER_FILES += \
$$PWD/shaders/shadereffect.vert \
$$PWD/shaders/shadereffect.frag \
$$PWD/shaders/shadereffectfallback.vert \
- $$PWD/shaders/shadereffectfallback.frag
+ $$PWD/shaders/shadereffectfallback.frag \
+ $$PWD/shaders/sprite_core.vert \
+ $$PWD/shaders/sprite_core.frag \
+ $$PWD/shaders/shadereffect_core.vert \
+ $$PWD/shaders/shadereffect_core.frag \
+ $$PWD/shaders/shadereffectfallback_core.vert \
+ $$PWD/shaders/shadereffectfallback_core.frag
RESOURCES += \
$$PWD/items.qrc
diff --git a/src/quick/items/items.qrc b/src/quick/items/items.qrc
index 837cffb65a..671d8acdbb 100644
--- a/src/quick/items/items.qrc
+++ b/src/quick/items/items.qrc
@@ -6,5 +6,11 @@
<file>shaders/shadereffect.frag</file>
<file>shaders/shadereffectfallback.frag</file>
<file>shaders/shadereffectfallback.vert</file>
+ <file>shaders/shadereffect_core.frag</file>
+ <file>shaders/shadereffect_core.vert</file>
+ <file>shaders/shadereffectfallback_core.frag</file>
+ <file>shaders/shadereffectfallback_core.vert</file>
+ <file>shaders/sprite_core.frag</file>
+ <file>shaders/sprite_core.vert</file>
</qresource>
</RCC>
diff --git a/src/quick/items/shaders/shadereffect_core.frag b/src/quick/items/shaders/shadereffect_core.frag
new file mode 100644
index 0000000000..2163753edc
--- /dev/null
+++ b/src/quick/items/shaders/shadereffect_core.frag
@@ -0,0 +1,13 @@
+#version 150 core
+
+in vec2 qt_TexCoord0;
+
+out vec4 fragColor;
+
+uniform sampler2D source;
+uniform float qt_Opacity;
+
+void main()
+{
+ fragColor = texture(source, qt_TexCoord0) * qt_Opacity;
+} \ No newline at end of file
diff --git a/src/quick/items/shaders/shadereffect_core.vert b/src/quick/items/shaders/shadereffect_core.vert
new file mode 100644
index 0000000000..2ed2d47b5f
--- /dev/null
+++ b/src/quick/items/shaders/shadereffect_core.vert
@@ -0,0 +1,14 @@
+#version 150 core
+
+in vec4 qt_Vertex;
+in vec2 qt_MultiTexCoord0;
+
+out vec2 qt_TexCoord0;
+
+uniform mat4 qt_Matrix;
+
+void main()
+{
+ qt_TexCoord0 = qt_MultiTexCoord0;
+ gl_Position = qt_Matrix * qt_Vertex;
+} \ No newline at end of file
diff --git a/src/quick/items/shaders/shadereffectfallback_core.frag b/src/quick/items/shaders/shadereffectfallback_core.frag
new file mode 100644
index 0000000000..4abf124737
--- /dev/null
+++ b/src/quick/items/shaders/shadereffectfallback_core.frag
@@ -0,0 +1,8 @@
+#version 150 core
+
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = vec4(1., 0., 1., 1.);
+} \ No newline at end of file
diff --git a/src/quick/items/shaders/shadereffectfallback_core.vert b/src/quick/items/shaders/shadereffectfallback_core.vert
new file mode 100644
index 0000000000..b1ca84cc6d
--- /dev/null
+++ b/src/quick/items/shaders/shadereffectfallback_core.vert
@@ -0,0 +1,10 @@
+#version 150 core
+
+in vec4 v;
+
+uniform mat4 qt_Matrix;
+
+void main()
+{
+ gl_Position = qt_Matrix * v;
+} \ No newline at end of file
diff --git a/src/quick/items/shaders/sprite_core.frag b/src/quick/items/shaders/sprite_core.frag
new file mode 100644
index 0000000000..c1087a8754
--- /dev/null
+++ b/src/quick/items/shaders/sprite_core.frag
@@ -0,0 +1,16 @@
+#version 150 core
+
+in vec4 fTexS;
+in float progress;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform float qt_Opacity;
+
+void main()
+{
+ fragColor = mix(texture(_qt_texture, fTexS.xy),
+ texture(_qt_texture, fTexS.zw),
+ progress) * qt_Opacity;
+} \ No newline at end of file
diff --git a/src/quick/items/shaders/sprite_core.vert b/src/quick/items/shaders/sprite_core.vert
new file mode 100644
index 0000000000..5027bf03fc
--- /dev/null
+++ b/src/quick/items/shaders/sprite_core.vert
@@ -0,0 +1,24 @@
+#version 150 core
+
+in vec2 vPos;
+in vec2 vTex;
+
+out vec4 fTexS;
+out float progress;
+
+uniform vec3 animData; // w,h(premultiplied of anim), interpolation progress
+uniform vec4 animPos; // x,y, x,y (two frames for interpolation)
+uniform mat4 qt_Matrix;
+
+void main()
+{
+ progress = animData.z;
+
+ // Calculate frame location in texture
+ fTexS.xy = animPos.xy + vTex.xy * animData.xy;
+
+ // Next frame is also passed, for interpolation
+ fTexS.zw = animPos.zw + vTex.xy * animData.xy;
+
+ gl_Position = qt_Matrix * vec4(vPos.x, vPos.y, 0, 1);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 3782cab5d3..49c2cc8178 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -46,6 +46,7 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLFramebufferObject>
+#include <QtGui/QOpenGLVertexArrayObject>
#include <private/qqmlprofilerservice_p.h>
@@ -57,7 +58,7 @@
QT_BEGIN_NAMESPACE
-extern QByteArray qsgShaderRewriter_insertZAttributes(const char *input);
+extern QByteArray qsgShaderRewriter_insertZAttributes(const char *input, QSurfaceFormat::OpenGLContextProfile profile);
namespace QSGBatchRenderer
{
@@ -132,10 +133,12 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material)
#endif
QSGMaterialShader *s = material->createShader();
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QSurfaceFormat::OpenGLContextProfile profile = ctx->format().profile();
QOpenGLShaderProgram *p = s->program();
p->addShaderFromSourceCode(QOpenGLShader::Vertex,
- qsgShaderRewriter_insertZAttributes(s->vertexShader()));
+ qsgShaderRewriter_insertZAttributes(s->vertexShader(), profile));
p->addShaderFromSourceCode(QOpenGLShader::Fragment,
s->fragmentShader());
@@ -761,6 +764,7 @@ Renderer::Renderer(QSGRenderContext *ctx)
, m_zRange(0)
, m_currentMaterial(0)
, m_currentShader(0)
+ , m_vao(0)
{
setNodeUpdater(new Updater(this));
@@ -801,6 +805,13 @@ Renderer::Renderer(QSGRenderContext *ctx)
qDebug() << "Batch thresholds: nodes:" << m_batchNodeThreshold << " vertices:" << m_batchVertexThreshold;
qDebug() << "Using buffer strategy:" << (m_bufferStrategy == GL_STATIC_DRAW ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream"));
}
+
+ // If rendering with an OpenGL Core profile context, we need to create a VAO
+ // to hold our vertex specification state.
+ if (context()->openglContext()->format().profile() == QSurfaceFormat::CoreProfile) {
+ m_vao = new QOpenGLVertexArrayObject(this);
+ m_vao->create();
+ }
}
static void qsg_wipeBuffer(Buffer *buffer, QOpenGLFunctions *funcs)
@@ -2211,6 +2222,17 @@ void Renderer::deleteRemovedElements()
m_elementsToDelete.reset();
}
+void Renderer::preprocess()
+{
+ // Bind our VAO. It's important that we do this here as the
+ // QSGRenderer::preprocess() call may well do work that requires
+ // a bound VAO.
+ if (m_vao)
+ m_vao->bind();
+
+ QSGRenderer::preprocess();
+}
+
void Renderer::render()
{
if (Q_UNLIKELY(debug_dump)) {
@@ -2318,6 +2340,9 @@ void Renderer::render()
renderBatches();
m_rebuild = 0;
+
+ if (m_vao)
+ m_vao->release();
}
void Renderer::prepareRenderNode(RenderNodeElement *e)
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index aacf482ead..95e111552d 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -50,6 +50,8 @@
QT_BEGIN_NAMESPACE
+class QOpenGLVertexArrayObject;
+
namespace QSGBatchRenderer
{
@@ -398,6 +400,7 @@ public:
protected:
void nodeChanged(QSGNode *node, QSGNode::DirtyState state);
+ void preprocess() Q_DECL_OVERRIDE;
void render();
private:
@@ -481,6 +484,9 @@ private:
QSGMaterialShader *m_currentProgram;
ShaderManager::Shader *m_currentShader;
const QSGClipNode *m_currentClip;
+
+ // For minimal OpenGL core profile support
+ QOpenGLVertexArrayObject *m_vao;
};
Batch *Renderer::newBatch()
diff --git a/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp b/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp
index eade198cd0..8c7c806cad 100644
--- a/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp
+++ b/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include <QtCore>
+#include <QtGui/QSurfaceFormat>
// Duct Tape tokenizer for the purpose of parsing and rewriting
// shader source code
@@ -173,7 +174,7 @@ Tokenizer::Token Tokenizer::next()
using namespace QSGShaderRewriter;
-QByteArray qsgShaderRewriter_insertZAttributes(const char *input)
+QByteArray qsgShaderRewriter_insertZAttributes(const char *input, QSurfaceFormat::OpenGLContextProfile profile)
{
Tokenizer tok;
tok.initialize(input);
@@ -182,15 +183,33 @@ QByteArray qsgShaderRewriter_insertZAttributes(const char *input)
Tokenizer::Token t = tok.next();
// First find "void main() { ... "
+ const char* voidPos;
while (t != Tokenizer::Token_EOF) {
if (lt == Tokenizer::Token_Void && t == Tokenizer::Token_Identifier) {
if (qstrncmp("main", tok.identifier, 4) == 0)
break;
}
+ voidPos = tok.pos - 4;
lt = t;
t = tok.next();
}
+ QByteArray result;
+ result.reserve(1024);
+ result += QByteArray::fromRawData(input, voidPos - input);
+ switch (profile) {
+ case QSurfaceFormat::NoProfile:
+ case QSurfaceFormat::CompatibilityProfile:
+ result += QByteArrayLiteral("attribute highp float _qt_order;\n");
+ result += QByteArrayLiteral("uniform highp float _qt_zRange;\n");
+ break;
+
+ case QSurfaceFormat::CoreProfile:
+ result += QByteArrayLiteral("in float _qt_order;\n");
+ result += QByteArrayLiteral("uniform float _qt_zRange;\n");
+ break;
+ }
+
// Find first brace '{'
while (t != Tokenizer::Token_EOF && t != Tokenizer::Token_OpenBrace) t = tok.next();
int braceDepth = 1;
@@ -202,12 +221,8 @@ QByteArray qsgShaderRewriter_insertZAttributes(const char *input)
case Tokenizer::Token_CloseBrace:
braceDepth--;
if (braceDepth == 0) {
- QByteArray result;
- result.reserve(1024);
- result += "attribute highp float _qt_order;\n";
- result += "uniform highp float _qt_zRange;\n";
- result += QByteArray::fromRawData(input, tok.pos - 1 - input);
- result += " gl_Position.z = gl_Position.z * _qt_zRange + _qt_order;\n";
+ result += QByteArray::fromRawData(voidPos, tok.pos - 1 - voidPos);
+ result += QByteArrayLiteral(" gl_Position.z = gl_Position.z * _qt_zRange + _qt_order;\n");
result += QByteArray(tok.pos - 1);
return result;
}
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index 8585caa22d..58c843a286 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -60,7 +60,7 @@ static QElapsedTimer qsg_render_timer;
QSGDistanceFieldGlyphCache::Texture QSGDistanceFieldGlyphCache::s_emptyTexture;
-QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, const QRawFont &font)
+QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font)
: m_manager(man)
, m_pendingGlyphs(64)
{
@@ -74,6 +74,8 @@ QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCach
m_referenceFont = font;
m_referenceFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(m_doubleGlyphResolution));
Q_ASSERT(m_referenceFont.isValid());
+
+ m_coreProfile = (c->format().profile() == QSurfaceFormat::CoreProfile);
}
QSGDistanceFieldGlyphCache::~QSGDistanceFieldGlyphCache()
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index f9e59f9c7f..f2d7dc07ca 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -66,6 +66,7 @@ class QImage;
class TextureReference;
class QSGDistanceFieldGlyphCacheManager;
class QSGDistanceFieldGlyphNode;
+class QOpenGLContext;
class Q_QUICK_PRIVATE_EXPORT QSGRectangleNode : public QSGGeometryNode
{
@@ -149,7 +150,7 @@ public:
class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldGlyphCache
{
public:
- QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, const QRawFont &font);
+ QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font);
virtual ~QSGDistanceFieldGlyphCache();
struct Metrics {
@@ -246,6 +247,8 @@ protected:
GlyphData &glyphData(glyph_t glyph);
+ inline bool isCoreProfile() const { return m_coreProfile; }
+
private:
QSGDistanceFieldGlyphCacheManager *m_manager;
@@ -253,6 +256,7 @@ private:
int m_glyphCount;
bool m_doubleGlyphResolution;
+ bool m_coreProfile;
QList<Texture> m_textures;
QHash<glyph_t, GlyphData> m_glyphsData;
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 1f219e735f..fa095b8165 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -391,12 +391,13 @@ QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRaw
cache = new QSGSharedDistanceFieldGlyphCache(keyName,
sharedGraphicsCache,
m_distanceFieldCacheManager,
+ openglContext(),
font);
}
}
}
if (!cache)
- cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, font);
+ cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, openglContext(), font);
m_distanceFieldCacheManager->insertCache(font, cache);
}
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
index 25ff98bc67..c5c4e18e37 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
@@ -48,16 +48,23 @@
#include <qopenglfunctions.h>
#include <qmath.h>
+#if !defined(QT_OPENGL_ES_2)
+#include <QtGui/qopenglfunctions_3_2_core.h>
+#endif
+
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(qmlUseGlyphCacheWorkaround, QML_USE_GLYPHCACHE_WORKAROUND)
-QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, const QRawFont &font)
- : QSGDistanceFieldGlyphCache(man, font)
+QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font)
+ : QSGDistanceFieldGlyphCache(man, c, font)
, m_maxTextureSize(0)
, m_maxTextureCount(3)
, m_blitProgram(0)
, m_fboGuard(0)
+#if !defined(QT_OPENGL_ES_2)
+ , m_funcs(0)
+#endif
{
m_blitVertexCoordinateArray[0] = -1.0f;
m_blitVertexCoordinateArray[1] = -1.0f;
@@ -177,17 +184,22 @@ void QSGDefaultDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField>
}
}
+#if !defined(QT_OPENGL_ES_2)
+ const GLenum format = isCoreProfile() ? GL_RED : GL_ALPHA;
+#else
+ const GLenum format = GL_ALPHA;
+#endif
if (useTextureUploadWorkaround()) {
for (int i = 0; i < glyph.height(); ++i) {
glTexSubImage2D(GL_TEXTURE_2D, 0,
c.x, c.y + i, glyph.width(),1,
- GL_ALPHA, GL_UNSIGNED_BYTE,
+ format, GL_UNSIGNED_BYTE,
glyph.scanLine(i));
}
} else {
glTexSubImage2D(GL_TEXTURE_2D, 0,
c.x, c.y, glyph.width(), glyph.height(),
- GL_ALPHA, GL_UNSIGNED_BYTE,
+ format, GL_UNSIGNED_BYTE,
glyph.constBits());
}
}
@@ -230,8 +242,14 @@ void QSGDefaultDistanceFieldGlyphCache::createTexture(TextureInfo *texInfo, int
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#if !defined(QT_OPENGL_ES_2)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ const GLint internalFormat = isCoreProfile() ? GL_R8 : GL_ALPHA;
+ const GLenum format = isCoreProfile() ? GL_RED : GL_ALPHA;
+#else
+ const GLint internalFormat = GL_ALPHA;
+ const GLenum format = GL_ALPHA;
#endif
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, 0);
texInfo->size = QSize(width, height);
@@ -267,22 +285,74 @@ void QSGDefaultDistanceFieldGlyphCache::resizeTexture(TextureInfo *texInfo, int
updateTexture(oldTexture, texInfo->texture, texInfo->size);
+#if !defined(QT_OPENGL_ES_2)
+ if (isCoreProfile() && !useTextureResizeWorkaround()) {
+ // For an OpenGL Core Profile we can use http://www.opengl.org/wiki/Framebuffer#Blitting
+ // to efficiently copy the contents of the old texture to the new texture
+ // TODO: Use ARB_copy_image if available of if we have >=4.3 context
+ if (!m_funcs) {
+ m_funcs = ctx->versionFunctions<QOpenGLFunctions_3_2_Core>();
+ Q_ASSERT(m_funcs);
+ m_funcs->initializeOpenGLFunctions();
+ }
+
+ // Create a framebuffer object to which we can attach our old and new textures (to
+ // the first two color buffer attachment points)
+ if (!m_fboGuard) {
+ GLuint fbo;
+ m_funcs->glGenFramebuffers(1, &fbo);
+ m_fboGuard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
+ }
+
+ // Bind the FBO to both the GL_READ_FRAMEBUFFER? and GL_DRAW_FRAMEBUFFER targets
+ m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, m_fboGuard->id());
+
+ // Bind the old texture to GL_COLOR_ATTACHMENT0
+ m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, oldTexture, 0);
+
+ // Bind the new texture to GL_COLOR_ATTACHMENT1
+ m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
+ GL_TEXTURE_2D, texInfo->texture, 0);
+
+ // Set the source and destination buffers
+ m_funcs->glReadBuffer(GL_COLOR_ATTACHMENT0);
+ m_funcs->glDrawBuffer(GL_COLOR_ATTACHMENT1);
+
+ // Do the blit
+ m_funcs->glBlitFramebuffer(0, 0, oldWidth, oldHeight,
+ 0, 0, oldWidth, oldHeight,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ // Reset the default framebuffer
+ m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ return;
+ } else if (useTextureResizeWorkaround()) {
+#else
if (useTextureResizeWorkaround()) {
+#endif
GLint alignment = 4; // default value
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+#if !defined(QT_OPENGL_ES_2)
+ const GLenum format = isCoreProfile() ? GL_RED : GL_ALPHA;
+#else
+ const GLenum format = GL_ALPHA;
+#endif
+
if (useTextureUploadWorkaround()) {
for (int i = 0; i < texInfo->image.height(); ++i) {
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, i, oldWidth, 1,
- GL_ALPHA, GL_UNSIGNED_BYTE,
+ format, GL_UNSIGNED_BYTE,
texInfo->image.scanLine(i));
}
} else {
glTexSubImage2D(GL_TEXTURE_2D, 0,
0, 0, oldWidth, oldHeight,
- GL_ALPHA, GL_UNSIGNED_BYTE,
+ format, GL_UNSIGNED_BYTE,
texInfo->image.constBits());
}
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
index 3fee6c9ef3..a5833af5fb 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
@@ -51,10 +51,14 @@
QT_BEGIN_NAMESPACE
class QOpenGLSharedResourceGuard;
+#if !defined(QT_OPENGL_ES_2)
+class QOpenGLFunctions_3_2_Core;
+#endif
+
class Q_QUICK_PRIVATE_EXPORT QSGDefaultDistanceFieldGlyphCache : public QSGDistanceFieldGlyphCache
{
public:
- QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, const QRawFont &font);
+ QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font);
virtual ~QSGDefaultDistanceFieldGlyphCache();
void requestGlyphs(const QSet<glyph_t> &glyphs);
@@ -133,6 +137,9 @@ private:
GLfloat m_blitTextureCoordinateArray[8];
QOpenGLSharedResourceGuard *m_fboGuard;
+#if !defined(QT_OPENGL_ES_2)
+ QOpenGLFunctions_3_2_Core *m_funcs;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
index 20e1210b68..cc0218aefd 100644
--- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
@@ -199,8 +199,9 @@ namespace {
QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteArray &cacheId,
QPlatformSharedGraphicsCache *sharedGraphicsCache,
QSGDistanceFieldGlyphCacheManager *man,
+ QOpenGLContext *c,
const QRawFont &font)
- : QSGDistanceFieldGlyphCache(man, font)
+ : QSGDistanceFieldGlyphCache(man, c, font)
, m_cacheId(cacheId)
, m_sharedGraphicsCache(sharedGraphicsCache)
, m_isInSceneGraphUpdate(false)
@@ -227,7 +228,6 @@ QSGSharedDistanceFieldGlyphCache::QSGSharedDistanceFieldGlyphCache(const QByteAr
this, SLOT(reportItemsInvalidated(QByteArray,QVector<quint32>)),
Qt::DirectConnection);
- QOpenGLContext *c = QOpenGLContext::currentContext();
Q_ASSERT(c);
QQuickWindow *window = static_cast<QQuickWindow *>(c->surface());
Q_ASSERT(window != 0);
diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
index a8d70be732..d72d2a740f 100644
--- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
@@ -55,6 +55,7 @@ public:
explicit QSGSharedDistanceFieldGlyphCache(const QByteArray &cacheId,
QPlatformSharedGraphicsCache *sharedGraphicsCache,
QSGDistanceFieldGlyphCacheManager *man,
+ QOpenGLContext *c,
const QRawFont &font);
~QSGSharedDistanceFieldGlyphCache();
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index aebc2ece9c..6f64c881a8 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -126,5 +126,37 @@ OTHER_FILES += \
$$PWD/shaders/textmask.vert \
$$PWD/shaders/texture.frag \
$$PWD/shaders/vertexcolor.frag \
- $$PWD/shaders/vertexcolor.vert
+ $$PWD/shaders/vertexcolor.vert \
+ $$PWD/shaders/24bittextmask_core.frag \
+ $$PWD/shaders/8bittextmask_core.frag \
+ $$PWD/shaders/distancefieldoutlinetext_core.frag \
+ $$PWD/shaders/distancefieldshiftedtext_core.frag \
+ $$PWD/shaders/distancefieldshiftedtext_core.vert \
+ $$PWD/shaders/distancefieldtext_core.frag \
+ $$PWD/shaders/distancefieldtext_core.vert \
+ $$PWD/shaders/flatcolor_core.frag \
+ $$PWD/shaders/flatcolor_core.vert \
+ $$PWD/shaders/hiqsubpixeldistancefieldtext_core.frag \
+ $$PWD/shaders/hiqsubpixeldistancefieldtext_core.vert \
+ $$PWD/shaders/loqsubpixeldistancefieldtext_core.frag \
+ $$PWD/shaders/loqsubpixeldistancefieldtext_core.vert \
+ $$PWD/shaders/opaquetexture_core.frag \
+ $$PWD/shaders/opaquetexture_core.vert \
+ $$PWD/shaders/outlinedtext_core.frag \
+ $$PWD/shaders/outlinedtext_core.vert \
+ $$PWD/shaders/rendernode_core.frag \
+ $$PWD/shaders/rendernode_core.vert \
+ $$PWD/shaders/smoothcolor_core.frag \
+ $$PWD/shaders/smoothcolor_core.vert \
+ $$PWD/shaders/smoothtexture_core.frag \
+ $$PWD/shaders/smoothtexture_core.vert \
+ $$PWD/shaders/stencilclip_core.frag \
+ $$PWD/shaders/stencilclip_core.vert \
+ $$PWD/shaders/styledtext_core.frag \
+ $$PWD/shaders/styledtext_core.vert \
+ $$PWD/shaders/textmask_core.frag \
+ $$PWD/shaders/textmask_core.vert \
+ $$PWD/shaders/texture_core.frag \
+ $$PWD/shaders/vertexcolor_core.frag \
+ $$PWD/shaders/vertexcolor_core.vert
diff --git a/src/quick/scenegraph/scenegraph.qrc b/src/quick/scenegraph/scenegraph.qrc
index 5299ec6d9f..2be8b246d3 100644
--- a/src/quick/scenegraph/scenegraph.qrc
+++ b/src/quick/scenegraph/scenegraph.qrc
@@ -32,5 +32,37 @@
<file>shaders/rendernode.frag</file>
<file>shaders/stencilclip.frag</file>
<file>shaders/stencilclip.vert</file>
+ <file>shaders/8bittextmask_core.frag</file>
+ <file>shaders/24bittextmask_core.frag</file>
+ <file>shaders/distancefieldoutlinetext_core.frag</file>
+ <file>shaders/distancefieldshiftedtext_core.frag</file>
+ <file>shaders/distancefieldshiftedtext_core.vert</file>
+ <file>shaders/distancefieldtext_core.frag</file>
+ <file>shaders/distancefieldtext_core.vert</file>
+ <file>shaders/flatcolor_core.frag</file>
+ <file>shaders/flatcolor_core.vert</file>
+ <file>shaders/hiqsubpixeldistancefieldtext_core.frag</file>
+ <file>shaders/hiqsubpixeldistancefieldtext_core.vert</file>
+ <file>shaders/loqsubpixeldistancefieldtext_core.frag</file>
+ <file>shaders/loqsubpixeldistancefieldtext_core.vert</file>
+ <file>shaders/opaquetexture_core.frag</file>
+ <file>shaders/opaquetexture_core.vert</file>
+ <file>shaders/outlinedtext_core.frag</file>
+ <file>shaders/outlinedtext_core.vert</file>
+ <file>shaders/rendernode_core.frag</file>
+ <file>shaders/rendernode_core.vert</file>
+ <file>shaders/smoothcolor_core.frag</file>
+ <file>shaders/smoothcolor_core.vert</file>
+ <file>shaders/smoothtexture_core.frag</file>
+ <file>shaders/smoothtexture_core.vert</file>
+ <file>shaders/stencilclip_core.frag</file>
+ <file>shaders/stencilclip_core.vert</file>
+ <file>shaders/styledtext_core.frag</file>
+ <file>shaders/styledtext_core.vert</file>
+ <file>shaders/textmask_core.frag</file>
+ <file>shaders/textmask_core.vert</file>
+ <file>shaders/texture_core.frag</file>
+ <file>shaders/vertexcolor_core.frag</file>
+ <file>shaders/vertexcolor_core.vert</file>
</qresource>
</RCC>
diff --git a/src/quick/scenegraph/shaders/24bittextmask.frag b/src/quick/scenegraph/shaders/24bittextmask.frag
index ac62e7b642..5c21e202f9 100644
--- a/src/quick/scenegraph/shaders/24bittextmask.frag
+++ b/src/quick/scenegraph/shaders/24bittextmask.frag
@@ -1,10 +1,10 @@
varying highp vec2 sampleCoord;
-uniform lowp sampler2D texture;
+uniform lowp sampler2D _qt_texture;
uniform lowp float color; // just the alpha, really...
void main()
{
- lowp vec4 glyph = texture2D(texture, sampleCoord);
+ lowp vec4 glyph = texture2D(_qt_texture, sampleCoord);
gl_FragColor = vec4(glyph.rgb * color, glyph.a);
} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/24bittextmask_core.frag b/src/quick/scenegraph/shaders/24bittextmask_core.frag
new file mode 100644
index 0000000000..29d1f23017
--- /dev/null
+++ b/src/quick/scenegraph/shaders/24bittextmask_core.frag
@@ -0,0 +1,14 @@
+#version 150 core
+
+in vec2 sampleCoord;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform float color; // just the alpha, really...
+
+void main()
+{
+ vec4 glyph = texture(_qt_texture, sampleCoord);
+ fragColor = vec4(glyph.rgb * color, glyph.a);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/8bittextmask.frag b/src/quick/scenegraph/shaders/8bittextmask.frag
index f2f06e8e07..44ffb279cb 100644
--- a/src/quick/scenegraph/shaders/8bittextmask.frag
+++ b/src/quick/scenegraph/shaders/8bittextmask.frag
@@ -1,9 +1,9 @@
varying highp vec2 sampleCoord;
-uniform lowp sampler2D texture;
+uniform lowp sampler2D _qt_texture;
uniform lowp vec4 color;
void main()
{
- gl_FragColor = color * texture2D(texture, sampleCoord).a;
+ gl_FragColor = color * texture2D(_qt_texture, sampleCoord).a;
} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/8bittextmask_core.frag b/src/quick/scenegraph/shaders/8bittextmask_core.frag
new file mode 100644
index 0000000000..2d67a4676a
--- /dev/null
+++ b/src/quick/scenegraph/shaders/8bittextmask_core.frag
@@ -0,0 +1,13 @@
+#version 150 core
+
+in vec2 sampleCoord;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform vec4 color;
+
+void main()
+{
+ fragColor = color * texture(_qt_texture, sampleCoord).r;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldoutlinetext_core.frag b/src/quick/scenegraph/shaders/distancefieldoutlinetext_core.frag
new file mode 100644
index 0000000000..80fa05ca3c
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldoutlinetext_core.frag
@@ -0,0 +1,20 @@
+#version 150 core
+
+in vec2 sampleCoord;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform vec4 color;
+uniform vec4 styleColor;
+uniform float alphaMin;
+uniform float alphaMax;
+uniform float outlineAlphaMax0;
+uniform float outlineAlphaMax1;
+
+void main()
+{
+ float d = texture(_qt_texture, sampleCoord).r;
+ fragColor = mix(styleColor, color, smoothstep(alphaMin, alphaMax, d))
+ * smoothstep(outlineAlphaMax0, outlineAlphaMax1, d);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldshiftedtext_core.frag b/src/quick/scenegraph/shaders/distancefieldshiftedtext_core.frag
new file mode 100644
index 0000000000..3f66965e78
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldshiftedtext_core.frag
@@ -0,0 +1,20 @@
+#version 150 core
+
+in vec2 sampleCoord;
+in vec2 shiftedSampleCoord;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform vec4 color;
+uniform vec4 styleColor;
+uniform float alphaMin;
+uniform float alphaMax;
+
+void main()
+{
+ float a = smoothstep(alphaMin, alphaMax, texture(_qt_texture, sampleCoord).r);
+ vec4 shifted = styleColor * smoothstep(alphaMin, alphaMax,
+ texture(_qt_texture, shiftedSampleCoord).r);
+ fragColor = mix(shifted, color, a);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldshiftedtext_core.vert b/src/quick/scenegraph/shaders/distancefieldshiftedtext_core.vert
new file mode 100644
index 0000000000..b7a3ecc667
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldshiftedtext_core.vert
@@ -0,0 +1,18 @@
+#version 150 core
+
+in vec4 vCoord;
+in vec2 tCoord;
+
+out vec2 sampleCoord;
+out vec2 shiftedSampleCoord;
+
+uniform mat4 matrix;
+uniform vec2 textureScale;
+uniform vec2 shift;
+
+void main()
+{
+ sampleCoord = tCoord * textureScale;
+ shiftedSampleCoord = (tCoord - shift) * textureScale;
+ gl_Position = matrix * vCoord;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldtext_core.frag b/src/quick/scenegraph/shaders/distancefieldtext_core.frag
new file mode 100644
index 0000000000..9c64a60d3d
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldtext_core.frag
@@ -0,0 +1,16 @@
+#version 150 core
+
+in vec2 sampleCoord;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform vec4 color;
+uniform float alphaMin;
+uniform float alphaMax;
+
+void main()
+{
+ fragColor = color * smoothstep(alphaMin, alphaMax,
+ texture(_qt_texture, sampleCoord).r);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/distancefieldtext_core.vert b/src/quick/scenegraph/shaders/distancefieldtext_core.vert
new file mode 100644
index 0000000000..7fc693d139
--- /dev/null
+++ b/src/quick/scenegraph/shaders/distancefieldtext_core.vert
@@ -0,0 +1,15 @@
+#version 150 core
+
+in vec4 vCoord;
+in vec2 tCoord;
+
+out vec2 sampleCoord;
+
+uniform mat4 matrix;
+uniform vec2 textureScale;
+
+void main()
+{
+ sampleCoord = tCoord * textureScale;
+ gl_Position = matrix * vCoord;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/flatcolor_core.frag b/src/quick/scenegraph/shaders/flatcolor_core.frag
new file mode 100644
index 0000000000..23a957ad7b
--- /dev/null
+++ b/src/quick/scenegraph/shaders/flatcolor_core.frag
@@ -0,0 +1,10 @@
+#version 150 core
+
+out vec4 fragColor;
+
+uniform vec4 color;
+
+void main()
+{
+ fragColor = color;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/flatcolor_core.vert b/src/quick/scenegraph/shaders/flatcolor_core.vert
new file mode 100644
index 0000000000..e33c591b95
--- /dev/null
+++ b/src/quick/scenegraph/shaders/flatcolor_core.vert
@@ -0,0 +1,10 @@
+#version 150 core
+
+in vec4 vCoord;
+
+uniform mat4 matrix;
+
+void main()
+{
+ gl_Position = matrix * vCoord;
+}
diff --git a/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext_core.frag b/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext_core.frag
new file mode 100644
index 0000000000..cf6ba2b8d9
--- /dev/null
+++ b/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext_core.frag
@@ -0,0 +1,32 @@
+#version 150 core
+
+in vec2 sampleCoord;
+in vec3 sampleFarLeft;
+in vec3 sampleNearLeft;
+in vec3 sampleNearRight;
+in vec3 sampleFarRight;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform vec4 color;
+uniform float alphaMin;
+uniform float alphaMax;
+
+void main()
+{
+ vec4 n;
+ n.x = textureProj(_qt_texture, sampleFarLeft).r;
+ n.y = textureProj(_qt_texture, sampleNearLeft).r;
+ float c = texture(_qt_texture, sampleCoord).r;
+ n.z = textureProj(_qt_texture, sampleNearRight).r;
+ n.w = textureProj(_qt_texture, sampleFarRight).r;
+
+ vec2 d = min(abs(n.yw - n.xz) * 2., 0.67);
+ vec2 lo = mix(vec2(alphaMin), vec2(0.5), d);
+ vec2 hi = mix(vec2(alphaMax), vec2(0.5), d);
+ n = smoothstep(lo.xxyy, hi.xxyy, n);
+ c = smoothstep(lo.x + lo.y, hi.x + hi.y, 2. * c);
+
+ fragColor = vec4(0.333 * (n.xyz + n.yzw + c), c) * color.w;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext_core.vert b/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext_core.vert
new file mode 100644
index 0000000000..936f74725b
--- /dev/null
+++ b/src/quick/scenegraph/shaders/hiqsubpixeldistancefieldtext_core.vert
@@ -0,0 +1,36 @@
+#version 150 core
+
+in vec4 vCoord;
+in vec2 tCoord;
+
+out vec2 sampleCoord;
+out vec3 sampleFarLeft;
+out vec3 sampleNearLeft;
+out vec3 sampleNearRight;
+out vec3 sampleFarRight;
+
+uniform mat4 matrix;
+uniform vec2 textureScale;
+uniform float fontScale;
+uniform vec4 vecDelta;
+
+void main()
+{
+ sampleCoord = tCoord * textureScale;
+ gl_Position = matrix * vCoord;
+
+ // Calculate neighbor pixel position in item space.
+ vec3 wDelta = gl_Position.w * vecDelta.xyw;
+ vec3 farLeft = vCoord.xyw - 0.667 * wDelta;
+ vec3 nearLeft = vCoord.xyw - 0.333 * wDelta;
+ vec3 nearRight = vCoord.xyw + 0.333 * wDelta;
+ vec3 farRight = vCoord.xyw + 0.667 * wDelta;
+
+ // Calculate neighbor texture coordinate.
+ vec2 scale = textureScale / fontScale;
+ vec2 base = sampleCoord - scale * vCoord.xy;
+ sampleFarLeft = vec3(base * farLeft.z + scale * farLeft.xy, farLeft.z);
+ sampleNearLeft = vec3(base * nearLeft.z + scale * nearLeft.xy, nearLeft.z);
+ sampleNearRight = vec3(base * nearRight.z + scale * nearRight.xy, nearRight.z);
+ sampleFarRight = vec3(base * farRight.z + scale * farRight.xy, farRight.z);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext_core.frag b/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext_core.frag
new file mode 100644
index 0000000000..2dd588d307
--- /dev/null
+++ b/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext_core.frag
@@ -0,0 +1,21 @@
+#version 150 core
+
+in vec3 sampleNearLeft;
+in vec3 sampleNearRight;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform vec4 color;
+uniform float alphaMin;
+uniform float alphaMax;
+
+void main()
+{
+ vec2 n;
+ n.x = textureProj(_qt_texture, sampleNearLeft).r;
+ n.y = textureProj(_qt_texture, sampleNearRight).r;
+ n = smoothstep(alphaMin, alphaMax, n);
+ float c = 0.5 * (n.x + n.y);
+ fragColor = vec4(n.x, c, n.y, c) * color.w;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext_core.vert b/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext_core.vert
new file mode 100644
index 0000000000..b887a70001
--- /dev/null
+++ b/src/quick/scenegraph/shaders/loqsubpixeldistancefieldtext_core.vert
@@ -0,0 +1,29 @@
+#version 150 core
+
+in vec4 vCoord;
+in vec2 tCoord;
+
+out vec3 sampleNearLeft;
+out vec3 sampleNearRight;
+
+uniform mat4 matrix;
+uniform vec2 textureScale;
+uniform float fontScale;
+uniform vec4 vecDelta;
+
+void main()
+{
+ vec2 sampleCoord = tCoord * textureScale;
+ gl_Position = matrix * vCoord;
+
+ // Calculate neighbor pixel position in item space.
+ vec3 wDelta = gl_Position.w * vecDelta.xyw;
+ vec3 nearLeft = vCoord.xyw - 0.25 * wDelta;
+ vec3 nearRight = vCoord.xyw + 0.25 * wDelta;
+
+ // Calculate neighbor texture coordinate.
+ vec2 scale = textureScale / fontScale;
+ vec2 base = sampleCoord - scale * vCoord.xy;
+ sampleNearLeft = vec3(base * nearLeft.z + scale * nearLeft.xy, nearLeft.z);
+ sampleNearRight = vec3(base * nearRight.z + scale * nearRight.xy, nearRight.z);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/opaquetexture_core.frag b/src/quick/scenegraph/shaders/opaquetexture_core.frag
new file mode 100644
index 0000000000..5f30e68677
--- /dev/null
+++ b/src/quick/scenegraph/shaders/opaquetexture_core.frag
@@ -0,0 +1,12 @@
+#version 150 core
+
+in vec2 qt_TexCoord;
+
+out vec4 fragColor;
+
+uniform sampler2D qt_Texture;
+
+void main()
+{
+ fragColor = texture(qt_Texture, qt_TexCoord);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/opaquetexture_core.vert b/src/quick/scenegraph/shaders/opaquetexture_core.vert
new file mode 100644
index 0000000000..419b1a825c
--- /dev/null
+++ b/src/quick/scenegraph/shaders/opaquetexture_core.vert
@@ -0,0 +1,14 @@
+#version 150 core
+
+uniform mat4 qt_Matrix;
+
+in vec4 qt_VertexPosition;
+in vec2 qt_VertexTexCoord;
+
+out vec2 qt_TexCoord;
+
+void main()
+{
+ qt_TexCoord = qt_VertexTexCoord;
+ gl_Position = qt_Matrix * qt_VertexPosition;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/outlinedtext_core.frag b/src/quick/scenegraph/shaders/outlinedtext_core.frag
new file mode 100644
index 0000000000..e19c8937f9
--- /dev/null
+++ b/src/quick/scenegraph/shaders/outlinedtext_core.frag
@@ -0,0 +1,25 @@
+#version 150 core
+
+in vec2 sampleCoord;
+in vec2 sCoordUp;
+in vec2 sCoordDown;
+in vec2 sCoordLeft;
+in vec2 sCoordRight;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform vec4 color;
+uniform vec4 styleColor;
+
+void main()
+{
+ float glyph = texture(_qt_texture, sampleCoord).r;
+ float outline = clamp(clamp(texture(_qt_texture, sCoordUp).r +
+ texture(_qt_texture, sCoordDown).r +
+ texture(_qt_texture, sCoordLeft).r +
+ texture(_qt_texture, sCoordRight).r,
+ 0.0, 1.0) - glyph,
+ 0.0, 1.0);
+ fragColor = outline * styleColor + glyph * color;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/outlinedtext_core.vert b/src/quick/scenegraph/shaders/outlinedtext_core.vert
new file mode 100644
index 0000000000..4aa13101fd
--- /dev/null
+++ b/src/quick/scenegraph/shaders/outlinedtext_core.vert
@@ -0,0 +1,24 @@
+#version 150 core
+
+in vec4 vCoord;
+in vec2 tCoord;
+
+out vec2 sampleCoord;
+out vec2 sCoordUp;
+out vec2 sCoordDown;
+out vec2 sCoordLeft;
+out vec2 sCoordRight;
+
+uniform mat4 matrix;
+uniform vec2 textureScale;
+uniform vec2 shift;
+
+void main()
+{
+ sampleCoord = tCoord * textureScale;
+ sCoordUp = (tCoord - vec2(0.0, -1.0)) * textureScale;
+ sCoordDown = (tCoord - vec2(0.0, 1.0)) * textureScale;
+ sCoordLeft = (tCoord - vec2(-1.0, 0.0)) * textureScale;
+ sCoordRight = (tCoord - vec2(1.0, 0.0)) * textureScale;
+ gl_Position = matrix * vCoord;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/rendernode_core.frag b/src/quick/scenegraph/shaders/rendernode_core.frag
new file mode 100644
index 0000000000..7c187265df
--- /dev/null
+++ b/src/quick/scenegraph/shaders/rendernode_core.frag
@@ -0,0 +1,12 @@
+#version 150 core
+
+uniform sampler2D tex;
+
+in vec2 t;
+
+out vec4 color;
+
+void main()
+{
+ fragColor = texture(tex, t);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/rendernode_core.vert b/src/quick/scenegraph/shaders/rendernode_core.vert
new file mode 100644
index 0000000000..a76d519a5a
--- /dev/null
+++ b/src/quick/scenegraph/shaders/rendernode_core.vert
@@ -0,0 +1,12 @@
+#version 150 core
+
+in vec4 av;
+in vec2 at;
+
+out vec2 t;
+
+void main()
+{
+ gl_Position = av;
+ t = at;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/smoothcolor_core.frag b/src/quick/scenegraph/shaders/smoothcolor_core.frag
new file mode 100644
index 0000000000..84533c2b40
--- /dev/null
+++ b/src/quick/scenegraph/shaders/smoothcolor_core.frag
@@ -0,0 +1,10 @@
+#version 150 core
+
+in vec4 color;
+
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = color;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/smoothcolor_core.vert b/src/quick/scenegraph/shaders/smoothcolor_core.vert
new file mode 100644
index 0000000000..1eed751ccd
--- /dev/null
+++ b/src/quick/scenegraph/shaders/smoothcolor_core.vert
@@ -0,0 +1,47 @@
+#version 150 core
+
+in vec4 vertex;
+in vec4 vertexColor;
+in vec2 vertexOffset;
+
+out vec4 color;
+
+uniform vec2 pixelSize;
+uniform mat4 matrix;
+uniform float opacity;
+
+void main()
+{
+ vec4 pos = matrix * vertex;
+ gl_Position = pos;
+
+ if (vertexOffset.x != 0.) {
+ vec4 delta = matrix[0] * vertexOffset.x;
+ vec2 dir = delta.xy * pos.w - pos.xy * delta.w;
+ vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);
+ dir -= ndir * delta.w * pos.w;
+ float numerator = dot(dir, ndir * pos.w * pos.w);
+ float scale = 0.0;
+ if (numerator < 0.0)
+ scale = 1.0;
+ else
+ scale = min(1.0, numerator / dot(dir, dir));
+ gl_Position += scale * delta;
+ }
+
+ if (vertexOffset.y != 0.) {
+ vec4 delta = matrix[1] * vertexOffset.y;
+ vec2 dir = delta.xy * pos.w - pos.xy * delta.w;
+ vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);
+ dir -= ndir * delta.w * pos.w;
+ float numerator = dot(dir, ndir * pos.w * pos.w);
+ float scale = 0.0;
+ if (numerator < 0.0)
+ scale = 1.0;
+ else
+ scale = min(1.0, numerator / dot(dir, dir));
+ gl_Position += scale * delta;
+ }
+
+ color = vertexColor * opacity;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/smoothtexture_core.frag b/src/quick/scenegraph/shaders/smoothtexture_core.frag
new file mode 100644
index 0000000000..8a9aefd4c8
--- /dev/null
+++ b/src/quick/scenegraph/shaders/smoothtexture_core.frag
@@ -0,0 +1,13 @@
+#version 150 core
+
+in vec2 texCoord;
+in float vertexOpacity;
+
+out vec4 fragColor;
+
+uniform sampler2D qt_Texture;
+
+void main()
+{
+ fragColor = texture(qt_Texture, texCoord) * vertexOpacity;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/smoothtexture_core.vert b/src/quick/scenegraph/shaders/smoothtexture_core.vert
new file mode 100644
index 0000000000..a2489a39c5
--- /dev/null
+++ b/src/quick/scenegraph/shaders/smoothtexture_core.vert
@@ -0,0 +1,54 @@
+#version 150 core
+
+in vec4 vertex;
+in vec2 multiTexCoord;
+in vec2 vertexOffset;
+in vec2 texCoordOffset;
+
+out vec2 texCoord;
+out float vertexOpacity;
+
+uniform vec2 pixelSize;
+uniform mat4 qt_Matrix;
+uniform float opacity;
+
+void main()
+{
+ vec4 pos = qt_Matrix * vertex;
+ gl_Position = pos;
+ texCoord = multiTexCoord;
+
+ if (vertexOffset.x != 0.) {
+ vec4 delta = qt_Matrix[0] * vertexOffset.x;
+ vec2 dir = delta.xy * pos.w - pos.xy * delta.w;
+ vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);
+ dir -= ndir * delta.w * pos.w;
+ float numerator = dot(dir, ndir * pos.w * pos.w);
+ float scale = 0.0;
+ if (numerator < 0.0)
+ scale = 1.0;
+ else
+ scale = min(1.0, numerator / dot(dir, dir));
+ gl_Position += scale * delta;
+ texCoord.x += scale * texCoordOffset.x;
+ }
+
+ if (vertexOffset.y != 0.) {
+ vec4 delta = qt_Matrix[1] * vertexOffset.y;
+ vec2 dir = delta.xy * pos.w - pos.xy * delta.w;
+ vec2 ndir = .5 * pixelSize * normalize(dir / pixelSize);
+ dir -= ndir * delta.w * pos.w;
+ float numerator = dot(dir, ndir * pos.w * pos.w);
+ float scale = 0.0;
+ if (numerator < 0.0)
+ scale = 1.0;
+ else
+ scale = min(1.0, numerator / dot(dir, dir));
+ gl_Position += scale * delta;
+ texCoord.y += scale * texCoordOffset.y;
+ }
+
+ bool onEdge = any(notEqual(vertexOffset, vec2(0.)));
+ bool outerEdge = all(equal(texCoordOffset, vec2(0.)));
+ vertexOpacity = onEdge && outerEdge ? 0. : opacity;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/stencilclip_core.frag b/src/quick/scenegraph/shaders/stencilclip_core.frag
new file mode 100644
index 0000000000..4d05de4ca9
--- /dev/null
+++ b/src/quick/scenegraph/shaders/stencilclip_core.frag
@@ -0,0 +1,8 @@
+#version 150 core
+
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = vec4(0.81, 0.83, 0.12, 1.0); // Trolltech green ftw!
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/stencilclip_core.vert b/src/quick/scenegraph/shaders/stencilclip_core.vert
new file mode 100644
index 0000000000..37e240c735
--- /dev/null
+++ b/src/quick/scenegraph/shaders/stencilclip_core.vert
@@ -0,0 +1,10 @@
+#version 150 core
+
+in vec4 vCoord;
+
+uniform mat4 matrix;
+
+void main()
+{
+ gl_Position = matrix * vCoord;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/styledtext_core.frag b/src/quick/scenegraph/shaders/styledtext_core.frag
new file mode 100644
index 0000000000..50f64c64a2
--- /dev/null
+++ b/src/quick/scenegraph/shaders/styledtext_core.frag
@@ -0,0 +1,18 @@
+#version 150 core
+
+in vec2 sampleCoord;
+in vec2 shiftedSampleCoord;
+
+out vec4 color;
+
+uniform sampler2D _qt_texture;
+uniform vec4 color;
+uniform vec4 styleColor;
+
+void main()
+{
+ float glyph = texture(_qt_texture, sampleCoord).a;
+ float style = clamp(texture(_qt_texture, shiftedSampleCoord).r - glyph,
+ 0.0, 1.0);
+ fragColor = style * styleColor + glyph * color;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/styledtext_core.vert b/src/quick/scenegraph/shaders/styledtext_core.vert
new file mode 100644
index 0000000000..b7a3ecc667
--- /dev/null
+++ b/src/quick/scenegraph/shaders/styledtext_core.vert
@@ -0,0 +1,18 @@
+#version 150 core
+
+in vec4 vCoord;
+in vec2 tCoord;
+
+out vec2 sampleCoord;
+out vec2 shiftedSampleCoord;
+
+uniform mat4 matrix;
+uniform vec2 textureScale;
+uniform vec2 shift;
+
+void main()
+{
+ sampleCoord = tCoord * textureScale;
+ shiftedSampleCoord = (tCoord - shift) * textureScale;
+ gl_Position = matrix * vCoord;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/textmask_core.frag b/src/quick/scenegraph/shaders/textmask_core.frag
new file mode 100644
index 0000000000..17dda53c97
--- /dev/null
+++ b/src/quick/scenegraph/shaders/textmask_core.frag
@@ -0,0 +1,14 @@
+#version 150 core
+
+in vec2 sampleCoord;
+
+out vec4 fragColor;
+
+uniform sampler2D _qt_texture;
+uniform vec4 color;
+
+void main()
+{
+ vec4 glyph = texture(_qt_texture, sampleCoord);
+ fragColor = vec4(glyph.rgb * color.a, glyph.a);
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/textmask_core.vert b/src/quick/scenegraph/shaders/textmask_core.vert
new file mode 100644
index 0000000000..619248dccb
--- /dev/null
+++ b/src/quick/scenegraph/shaders/textmask_core.vert
@@ -0,0 +1,15 @@
+#version 150 core
+
+in vec4 vCoord;
+in vec2 tCoord;
+
+out vec2 sampleCoord;
+
+uniform mat4 matrix;
+uniform vec2 textureScale;
+
+void main()
+{
+ sampleCoord = tCoord * textureScale;
+ gl_Position = matrix * vCoord;
+}
diff --git a/src/quick/scenegraph/shaders/texture_core.frag b/src/quick/scenegraph/shaders/texture_core.frag
new file mode 100644
index 0000000000..d9bdf6a238
--- /dev/null
+++ b/src/quick/scenegraph/shaders/texture_core.frag
@@ -0,0 +1,13 @@
+#version 150 core
+
+in vec2 qt_TexCoord;
+
+out vec4 fragColor;
+
+uniform sampler2D qt_Texture;
+uniform float opacity;
+
+void main()
+{
+ fragColor = texture(qt_Texture, qt_TexCoord) * opacity;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/vertexcolor_core.frag b/src/quick/scenegraph/shaders/vertexcolor_core.frag
new file mode 100644
index 0000000000..84533c2b40
--- /dev/null
+++ b/src/quick/scenegraph/shaders/vertexcolor_core.frag
@@ -0,0 +1,10 @@
+#version 150 core
+
+in vec4 color;
+
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = color;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/shaders/vertexcolor_core.vert b/src/quick/scenegraph/shaders/vertexcolor_core.vert
new file mode 100644
index 0000000000..219b840913
--- /dev/null
+++ b/src/quick/scenegraph/shaders/vertexcolor_core.vert
@@ -0,0 +1,15 @@
+#version 150 core
+
+in vec4 vertexCoord;
+in vec4 vertexColor;
+
+out vec4 color;
+
+uniform mat4 matrix;
+uniform float opacity;
+
+void main()
+{
+ gl_Position = matrix * vertexCoord;
+ color = vertexColor * opacity;
+} \ No newline at end of file
diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
index c7dd1a9799..1a1963dbca 100644
--- a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
+++ b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp
@@ -41,6 +41,7 @@
#include "qsgshadersourcebuilder_p.h"
+#include <QtGui/qopenglcontext.h>
#include <QtGui/qopenglshaderprogram.h>
#include <QtCore/qdebug.h>
@@ -48,6 +49,162 @@
QT_BEGIN_NAMESPACE
+namespace QSGShaderParser {
+
+struct Tokenizer {
+
+ enum Token {
+ Token_Invalid,
+ Token_Void,
+ Token_OpenBrace,
+ Token_CloseBrace,
+ Token_SemiColon,
+ Token_Identifier,
+ Token_Macro,
+ Token_Version,
+ Token_Extension,
+ Token_SingleLineComment,
+ Token_MultiLineCommentStart,
+ Token_MultiLineCommentEnd,
+ Token_NewLine,
+ Token_Unspecified,
+ Token_EOF
+ };
+
+ static const char *NAMES[];
+
+ void initialize(const char *input);
+ Token next();
+
+ const char *stream;
+ const char *pos;
+ const char *identifier;
+};
+
+const char *Tokenizer::NAMES[] = {
+ "Invalid",
+ "Void",
+ "OpenBrace",
+ "CloseBrace",
+ "SemiColon",
+ "Identifier",
+ "Macro",
+ "Version",
+ "Extension",
+ "SingleLineComment",
+ "MultiLineCommentStart",
+ "MultiLineCommentEnd",
+ "NewLine",
+ "Unspecified",
+ "EOF"
+};
+
+void Tokenizer::initialize(const char *input)
+{
+ stream = input;
+ pos = input;
+ identifier = input;
+}
+
+Tokenizer::Token Tokenizer::next()
+{
+ while (*pos != 0) {
+ char c = *pos++;
+ switch (c) {
+ case '/':
+ if (*pos == '/') {
+ // '//' comment
+ return Token_SingleLineComment;
+ } else if (*pos == '*') {
+ // /* */ comment
+ return Token_MultiLineCommentStart;
+ }
+ break;
+
+ case '*':
+ if (*pos == '/')
+ return Token_MultiLineCommentEnd;
+
+ case '\n':
+ return Token_NewLine;
+
+ case '\r':
+ if (*pos == '\n')
+ return Token_NewLine;
+
+ case '#': {
+ if (*pos == 'v' && pos[1] == 'e' && pos[2] == 'r' && pos[3] == 's'
+ && pos[4] == 'i' && pos[5] == 'o' && pos[6] == 'n') {
+ return Token_Version;
+ } else if (*pos == 'e' && pos[1] == 'x' && pos[2] == 't' && pos[3] == 'e'
+ && pos[4] == 'n' && pos[5] == 's' && pos[6] == 'i'&& pos[7] == 'o'
+ && pos[8] == 'n') {
+ return Token_Extension;
+ } else {
+ while (*pos != 0) {
+ if (*pos == '\n') {
+ ++pos;
+ break;
+ } else if (*pos == '\\') {
+ ++pos;
+ while (*pos != 0 && (*pos == ' ' || *pos == '\t'))
+ ++pos;
+ if (*pos != 0 && (*pos == '\n' || (*pos == '\r' && pos[1] == '\n')))
+ pos+=2;
+ } else {
+ ++pos;
+ }
+ }
+ }
+ break;
+ }
+
+ case ';':
+ return Token_SemiColon;
+
+ case 0:
+ return Token_EOF;
+
+ case '{':
+ return Token_OpenBrace;
+
+ case '}':
+ return Token_CloseBrace;
+
+ case ' ':
+ break;
+
+ case 'v': {
+ if (*pos == 'o' && pos[1] == 'i' && pos[2] == 'd') {
+ pos += 3;
+ return Token_Void;
+ }
+ // Fall-thru
+ }
+ default:
+ // Identifier...
+ if ((c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' ) || c == '_') {
+ identifier = pos - 1;
+ while (*pos != 0 && ((*pos >= 'a' && *pos <= 'z')
+ || (*pos >= 'A' && *pos <= 'Z')
+ || *pos == '_'
+ || (*pos >= '0' && *pos <= '9'))) {
+ ++pos;
+ }
+ return Token_Identifier;
+ } else {
+ return Token_Unspecified;
+ }
+ }
+ }
+
+ return Token_Invalid;
+}
+
+} // namespace QSGShaderParser
+
+using namespace QSGShaderParser;
+
QSGShaderSourceBuilder::QSGShaderSourceBuilder()
{
}
@@ -87,7 +244,7 @@ void QSGShaderSourceBuilder::appendSource(const QByteArray &source)
void QSGShaderSourceBuilder::appendSourceFile(const QString &fileName)
{
const QString resolvedFileName = resolveShaderPath(fileName);
- QFile f(fileName);
+ QFile f(resolvedFileName);
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Failed to find shader" << resolvedFileName;
return;
@@ -95,12 +252,152 @@ void QSGShaderSourceBuilder::appendSourceFile(const QString &fileName)
m_source += f.readAll();
}
+void QSGShaderSourceBuilder::addDefinition(const QByteArray &definition)
+{
+ if (definition.isEmpty())
+ return;
+
+ Tokenizer tok;
+ const char *input = m_source.constData();
+ tok.initialize(input);
+
+ // First find #version, #extension's and "void main() { ... "
+ const char *versionPos = 0;
+ const char *extensionPos = 0;
+ bool inSingleLineComment = false;
+ bool inMultiLineComment = false;
+ bool foundVersionStart = false;
+ bool foundExtensionStart = false;
+
+ Tokenizer::Token lt = Tokenizer::Token_Unspecified;
+ Tokenizer::Token t = tok.next();
+ while (t != Tokenizer::Token_EOF) {
+ // Handle comment blocks
+ if (t == Tokenizer::Token_MultiLineCommentStart )
+ inMultiLineComment = true;
+ if (t == Tokenizer::Token_MultiLineCommentEnd)
+ inMultiLineComment = false;
+ if (t == Tokenizer::Token_SingleLineComment)
+ inSingleLineComment = true;
+ if (t == Tokenizer::Token_NewLine && inSingleLineComment && !inMultiLineComment)
+ inSingleLineComment = false;
+
+ // Have we found #version, #extension or void main()?
+ if (t == Tokenizer::Token_Version && !inSingleLineComment && !inMultiLineComment)
+ foundVersionStart = true;
+
+ if (t == Tokenizer::Token_Extension && !inSingleLineComment && !inMultiLineComment)
+ foundExtensionStart = true;
+
+ if (foundVersionStart && t == Tokenizer::Token_NewLine) {
+ versionPos = tok.pos;
+ foundVersionStart = false;
+ } else if (foundExtensionStart && t == Tokenizer::Token_NewLine) {
+ extensionPos = tok.pos;
+ foundExtensionStart = false;
+ } else if (lt == Tokenizer::Token_Void && t == Tokenizer::Token_Identifier) {
+ if (qstrncmp("main", tok.identifier, 4) == 0)
+ break;
+ }
+
+ // Scan to next token
+ lt = t;
+ t = tok.next();
+ }
+
+ // Determine where to insert the definition.
+ // If we found #extension directives, insert after last one,
+ // else, if we found #version insert after #version
+ // otherwise, insert at beginning.
+ const char *insertionPos = extensionPos ? extensionPos : (versionPos ? versionPos : input);
+
+ // Construct a new shader string, inserting the definition
+ QByteArray newSource;
+ newSource.reserve(m_source.size() + definition.size() + 9);
+ newSource += QByteArray::fromRawData(input, insertionPos - input);
+ newSource += QByteArrayLiteral("#define ") + definition + QByteArrayLiteral("\n");
+ newSource += QByteArray::fromRawData(insertionPos, m_source.size() - (insertionPos - input));
+
+ m_source = newSource;
+}
+
+void QSGShaderSourceBuilder::removeVersion()
+{
+ Tokenizer tok;
+ const char *input = m_source.constData();
+ tok.initialize(input);
+
+ // First find #version beginning and end (if present)
+ const char *versionStartPos = 0;
+ const char *versionEndPos = 0;
+ bool inSingleLineComment = false;
+ bool inMultiLineComment = false;
+ bool foundVersionStart = false;
+
+ Tokenizer::Token lt = Tokenizer::Token_Unspecified;
+ Tokenizer::Token t = tok.next();
+ while (t != Tokenizer::Token_EOF) {
+ // Handle comment blocks
+ if (t == Tokenizer::Token_MultiLineCommentStart )
+ inMultiLineComment = true;
+ if (t == Tokenizer::Token_MultiLineCommentEnd)
+ inMultiLineComment = false;
+ if (t == Tokenizer::Token_SingleLineComment)
+ inSingleLineComment = true;
+ if (t == Tokenizer::Token_NewLine && inSingleLineComment && !inMultiLineComment)
+ inSingleLineComment = false;
+
+ // Have we found #version, #extension or void main()?
+ if (t == Tokenizer::Token_Version && !inSingleLineComment && !inMultiLineComment) {
+ versionStartPos = tok.pos - 1;
+ foundVersionStart = true;
+ } else if (foundVersionStart && t == Tokenizer::Token_NewLine) {
+ versionEndPos = tok.pos;
+ break;
+ } else if (lt == Tokenizer::Token_Void && t == Tokenizer::Token_Identifier) {
+ if (qstrncmp("main", tok.identifier, 4) == 0)
+ break;
+ }
+
+ // Scan to next token
+ lt = t;
+ t = tok.next();
+ }
+
+ if (versionStartPos == 0)
+ return;
+
+ // Construct a new shader string, inserting the definition
+ QByteArray newSource;
+ newSource.reserve(m_source.size() - (versionEndPos - versionStartPos));
+ newSource += QByteArray::fromRawData(input, versionStartPos - input);
+ newSource += QByteArray::fromRawData(versionEndPos, m_source.size() - (versionEndPos - versionStartPos));
+
+ m_source = newSource;
+}
+
QString QSGShaderSourceBuilder::resolveShaderPath(const QString &path) const
{
- // For now, just return the path unaltered.
- // TODO: Resolve to more specific filename based upon OpenGL profile and
- // version, platform, GPU type etc
- return path;
+ if (contextProfile() != QSurfaceFormat::CoreProfile) {
+ return path;
+ } else {
+ int idx = path.lastIndexOf(QStringLiteral("."));
+ QString resolvedPath;
+ if (idx != -1)
+ resolvedPath = path.left(idx)
+ + QStringLiteral("_core")
+ + path.right(path.length() - idx);
+ return resolvedPath;
+ }
+}
+
+QSurfaceFormat::OpenGLContextProfile QSGShaderSourceBuilder::contextProfile() const
+{
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ QSurfaceFormat::OpenGLContextProfile profile = QSurfaceFormat::NoProfile;
+ Q_ASSERT(context);
+ profile = context->format().profile();
+ return profile;
}
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h b/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h
index 8def250d4f..63f2d78767 100644
--- a/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h
+++ b/src/quick/scenegraph/util/qsgshadersourcebuilder_p.h
@@ -44,6 +44,7 @@
#include <private/qtquickglobal_p.h>
+#include <QtGui/qsurfaceformat.h>
#include <QtCore/qbytearray.h>
QT_BEGIN_NAMESPACE
@@ -64,11 +65,15 @@ public:
void appendSource(const QByteArray &source);
void appendSourceFile(const QString &fileName);
+ void addDefinition(const QByteArray &definition);
+ void removeVersion();
protected:
virtual QString resolveShaderPath(const QString &path) const;
private:
+ QSurfaceFormat::OpenGLContextProfile contextProfile() const;
+
QByteArray m_source;
};
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index b079100a37..ddee887bd1 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -682,14 +682,14 @@ void QSGPlainTexture::bind()
GLenum externalFormat = GL_RGBA;
GLenum internalFormat = GL_RGBA;
- const char *extensions = (const char *) glGetString(GL_EXTENSIONS);
- if (strstr(extensions, "GL_EXT_bgra")) {
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ if (context->hasExtension(QByteArrayLiteral("GL_EXT_bgra"))) {
externalFormat = GL_BGRA;
#ifdef QT_OPENGL_ES
internalFormat = GL_BGRA;
#endif
- } else if (strstr(extensions, "GL_EXT_texture_format_BGRA8888")
- || strstr(extensions, "GL_IMG_texture_format_BGRA8888")) {
+ } else if (context->hasExtension(QByteArrayLiteral("GL_EXT_texture_format_BGRA8888"))
+ || context->hasExtension(QByteArrayLiteral("GL_IMG_texture_format_BGRA8888"))) {
externalFormat = GL_BGRA;
internalFormat = GL_BGRA;
} else {
@@ -711,8 +711,7 @@ void QSGPlainTexture::bind()
if (m_has_mipmaps) {
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D);
+ context->functions()->glGenerateMipmap(GL_TEXTURE_2D);
m_mipmaps_generated = true;
}