aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/scenegraph')
-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
49 files changed, 1132 insertions, 38 deletions
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;
}