diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2014-12-09 15:09:20 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2014-12-09 15:09:26 +0100 |
commit | ff466a1881435f927f5df9ce1e5eac07d5591904 (patch) | |
tree | 760e068743e6a8e1cc4ec63bb2f8e7dcef88b3e2 /src/quick/scenegraph | |
parent | e04822f3c2a6b69b7d75e2039256aa2433c59dd2 (diff) | |
parent | 4a3f6e58b591f2fe2204f7cbc1efc8abb0aade74 (diff) |
Merge remote-tracking branch 'origin/5.4' into dev
Conflicts:
src/qml/jsruntime/qv4arraydata.cpp
src/qml/jsruntime/qv4context_p.h
src/qml/jsruntime/qv4globalobject.cpp
src/qml/jsruntime/qv4internalclass.cpp
src/quick/items/qquicktext_p.h
src/quick/items/qquicktextedit_p.h
src/quick/items/qquicktextinput_p.h
Change-Id: If07e483e03197cb997ef47a9c647a479cdb09f4c
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r-- | src/quick/scenegraph/qsgadaptationlayer.cpp | 162 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgadaptationlayer_p.h | 16 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp | 28 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h | 3 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultimagenode.cpp | 57 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultimagenode_p.h | 3 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp | 173 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgwindowsrenderloop.cpp | 21 | ||||
-rw-r--r-- | src/quick/scenegraph/scenegraph.pri | 1 | ||||
-rw-r--r-- | src/quick/scenegraph/util/qsgsimpletexturenode.cpp | 4 |
11 files changed, 222 insertions, 248 deletions
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index e0b96a45b6..7ddfdeb2d4 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -175,6 +175,11 @@ void QSGDistanceFieldGlyphCache::update() storeGlyphs(distanceFields); +#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG) + foreach (Texture texture, m_textures) + saveTexture(texture.textureId, texture.size.width(), texture.size.height()); +#endif + if (QSG_LOG_TIME_GLYPH().isDebugEnabled()) { quint64 now = qsg_render_timer.elapsed(); qCDebug(QSG_LOG_TIME_GLYPH, @@ -283,6 +288,163 @@ void QSGDistanceFieldGlyphCache::updateTexture(GLuint oldTex, GLuint newTex, con } } +#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG) +#include <QtGui/qopenglfunctions.h> + +void QSGDistanceFieldGlyphCache::saveTexture(GLuint textureId, int width, int height) const +{ + QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions(); + + GLuint fboId; + functions->glGenFramebuffers(1, &fboId); + + GLuint tmpTexture = 0; + functions->glGenTextures(1, &tmpTexture); + functions->glBindTexture(GL_TEXTURE_2D, tmpTexture); + functions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + functions->glBindTexture(GL_TEXTURE_2D, 0); + + functions->glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId); + functions->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, + tmpTexture, 0); + + functions->glActiveTexture(GL_TEXTURE0); + functions->glBindTexture(GL_TEXTURE_2D, textureId); + + functions->glDisable(GL_STENCIL_TEST); + functions->glDisable(GL_DEPTH_TEST); + functions->glDisable(GL_SCISSOR_TEST); + functions->glDisable(GL_BLEND); + + GLfloat textureCoordinateArray[8]; + textureCoordinateArray[0] = 0.0f; + textureCoordinateArray[1] = 0.0f; + textureCoordinateArray[2] = 1.0f; + textureCoordinateArray[3] = 0.0f; + textureCoordinateArray[4] = 1.0f; + textureCoordinateArray[5] = 1.0f; + textureCoordinateArray[6] = 0.0f; + textureCoordinateArray[7] = 1.0f; + + GLfloat vertexCoordinateArray[8]; + vertexCoordinateArray[0] = -1.0f; + vertexCoordinateArray[1] = -1.0f; + vertexCoordinateArray[2] = 1.0f; + vertexCoordinateArray[3] = -1.0f; + vertexCoordinateArray[4] = 1.0f; + vertexCoordinateArray[5] = 1.0f; + vertexCoordinateArray[6] = -1.0f; + vertexCoordinateArray[7] = 1.0f; + + functions->glViewport(0, 0, width, height); + functions->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray); + functions->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray); + + { + static const char *vertexShaderSource = + "attribute vec4 vertexCoordsArray; \n" + "attribute vec2 textureCoordArray; \n" + "varying vec2 textureCoords; \n" + "void main(void) \n" + "{ \n" + " gl_Position = vertexCoordsArray; \n" + " textureCoords = textureCoordArray; \n" + "} \n"; + + static const char *fragmentShaderSource = + "varying vec2 textureCoords; \n" + "uniform sampler2D texture; \n" + "void main() \n" + "{ \n" + " gl_FragColor = texture2D(texture, textureCoords); \n" + "} \n"; + + GLuint vertexShader = functions->glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = functions->glCreateShader(GL_FRAGMENT_SHADER); + + if (vertexShader == 0 || fragmentShader == 0) { + GLenum error = functions->glGetError(); + qWarning("QSGDistanceFieldGlyphCache::saveTexture: Failed to create shaders. (GL error: %x)", + error); + return; + } + + functions->glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); + functions->glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); + functions->glCompileShader(vertexShader); + + GLint len = 1; + functions->glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &len); + + char infoLog[2048]; + functions->glGetShaderInfoLog(vertexShader, 2048, NULL, infoLog); + if (qstrlen(infoLog) > 0) + qWarning("Problems compiling vertex shader:\n %s", infoLog); + + functions->glCompileShader(fragmentShader); + functions->glGetShaderInfoLog(fragmentShader, 2048, NULL, infoLog); + if (qstrlen(infoLog) > 0) + qWarning("Problems compiling fragment shader:\n %s", infoLog); + + GLuint shaderProgram = functions->glCreateProgram(); + functions->glAttachShader(shaderProgram, vertexShader); + functions->glAttachShader(shaderProgram, fragmentShader); + + functions->glBindAttribLocation(shaderProgram, 0, "vertexCoordsArray"); + functions->glBindAttribLocation(shaderProgram, 1, "textureCoordArray"); + + functions->glLinkProgram(shaderProgram); + functions->glGetProgramInfoLog(shaderProgram, 2048, NULL, infoLog); + if (qstrlen(infoLog) > 0) + qWarning("Problems linking shaders:\n %s", infoLog); + + functions->glUseProgram(shaderProgram); + functions->glEnableVertexAttribArray(0); + functions->glEnableVertexAttribArray(1); + + int textureUniformLocation = functions->glGetUniformLocation(shaderProgram, "texture"); + functions->glUniform1i(textureUniformLocation, 0); + } + + functions->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + { + GLenum error = functions->glGetError(); + if (error != GL_NO_ERROR) + qWarning("glDrawArrays reported error 0x%x", error); + } + + uchar *data = new uchar[width * height * 4]; + + functions->glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); + + QImage image(data, width, height, QImage::Format_ARGB32); + + QByteArray fileName = m_referenceFont.familyName().toLatin1() + '_' + QByteArray::number(textureId); + fileName = fileName.replace('/', '_').replace(' ', '_') + ".png"; + + image.save(QString::fromLocal8Bit(fileName)); + + { + GLenum error = functions->glGetError(); + if (error != GL_NO_ERROR) + qWarning("glReadPixels reported error 0x%x", error); + } + + functions->glDisableVertexAttribArray(0); + functions->glDisableVertexAttribArray(1); + + functions->glDeleteFramebuffers(1, &fboId); + functions->glDeleteTextures(1, &tmpTexture); + + delete[] data; +} +#endif + void QSGNodeVisitorEx::visitChildren(QSGNode *node) { for (QSGNode *child = node->firstChild(); child; child = child->nextSibling()) { diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index a63299fcde..ef21385ee6 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -126,17 +126,6 @@ public: class Q_QUICK_PRIVATE_EXPORT QSGImageNode : public QSGVisitableNode { public: - enum AntialiasingFlag - { - AntialiasingNone = 0, - AntialiasingLeft = 1, - AntialiasingRight = 2, - AntialiasingTop = 4, - AntialiasingBottom = 8, - AntialiasingAll = AntialiasingLeft | AntialiasingRight | AntialiasingBottom | AntialiasingTop - }; - Q_DECLARE_FLAGS(AntialiasingFlags, AntialiasingFlag) - virtual void setTargetRect(const QRectF &rect) = 0; virtual void setInnerTargetRect(const QRectF &rect) = 0; virtual void setInnerSourceRect(const QRectF &rect) = 0; @@ -151,7 +140,6 @@ public: virtual void setFiltering(QSGTexture::Filtering filtering) = 0; virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) = 0; virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) = 0; - virtual void setAntialiasing(AntialiasingFlags flags) { Q_UNUSED(flags); } virtual void update() = 0; @@ -357,6 +345,10 @@ protected: GlyphData &glyphData(glyph_t glyph); +#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG) + void saveTexture(GLuint textureId, int width, int height) const; +#endif + inline bool isCoreProfile() const { return m_coreProfile; } private: diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 50db3883a5..95388d82e0 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -357,7 +357,7 @@ void QSGContext::renderContextInitialized(QSGRenderContext *renderContext) // before without a context. Now the context is ready. if (!d->distanceFieldAntialiasingDecided) { d->distanceFieldAntialiasingDecided = true; -#ifndef Q_OS_WIN +#ifndef Q_OS_WIN32 if (renderContext->openglContext()->isOpenGLES()) d->distanceFieldAntialiasing = QSGGlyphNode::GrayAntialiasing; #endif diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp index 093e84b618..3d958245d2 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp @@ -48,6 +48,10 @@ QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(qmlUseGlyphCacheWorkaround, QML_USE_GLYPHCACHE_WORKAROUND) +#if !defined(QSG_DEFAULT_DISTANCEFIELD_GLYPH_CACHE_PADDING) +# define QSG_DEFAULT_DISTANCEFIELD_GLYPH_CACHE_PADDING 2 +#endif + QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font) : QSGDistanceFieldGlyphCache(man, c, font) , m_maxTextureSize(0) @@ -90,8 +94,9 @@ void QSGDefaultDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyph for (QSet<glyph_t>::const_iterator it = glyphs.constBegin(); it != glyphs.constEnd() ; ++it) { glyph_t glyphIndex = *it; + int padding = QSG_DEFAULT_DISTANCEFIELD_GLYPH_CACHE_PADDING; int glyphWidth = qCeil(glyphData(glyphIndex).boundingRect.width()) + distanceFieldRadius() * 2; - QSize glyphSize(glyphWidth, QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution())); + QSize glyphSize(glyphWidth + padding * 2, QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()) + padding * 2); QRect alloc = m_areaAllocator->allocate(glyphSize); if (alloc.isNull()) { @@ -101,7 +106,10 @@ void QSGDefaultDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyph TexCoord unusedCoord = glyphTexCoord(unusedGlyph); int unusedGlyphWidth = qCeil(glyphData(unusedGlyph).boundingRect.width()) + distanceFieldRadius() * 2; - m_areaAllocator->deallocate(QRect(unusedCoord.x, unusedCoord.y, unusedGlyphWidth, QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()))); + m_areaAllocator->deallocate(QRect(unusedCoord.x - padding, + unusedCoord.y - padding, + padding * 2 + unusedGlyphWidth, + padding * 2 + QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()))); m_unusedGlyphs.remove(unusedGlyph); m_glyphsTexture.remove(unusedGlyph); @@ -117,11 +125,14 @@ void QSGDefaultDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyph TextureInfo *tex = textureInfo(alloc.y() / maxTextureSize()); alloc = QRect(alloc.x(), alloc.y() % maxTextureSize(), alloc.width(), alloc.height()); + tex->allocatedArea |= alloc; + Q_ASSERT(tex->padding == padding || tex->padding < 0); + tex->padding = padding; GlyphPosition p; p.glyph = glyphIndex; - p.position = alloc.topLeft(); + p.position = alloc.topLeft() + QPoint(padding, padding); glyphPositions.append(p); glyphsToRender.append(glyphIndex); @@ -153,13 +164,14 @@ void QSGDefaultDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> glyphTextures[texInfo].append(glyphIndex); + int padding = texInfo->padding; int expectedWidth = qCeil(c.width + c.xMargin * 2); - if (glyph.width() != expectedWidth) - glyph = glyph.copy(0, 0, expectedWidth, glyph.height()); + glyph = glyph.copy(-padding, -padding, + expectedWidth + padding * 2, glyph.height() + padding * 2); if (useTextureResizeWorkaround()) { uchar *inBits = glyph.scanLine(0); - uchar *outBits = texInfo->image.scanLine(int(c.y)) + int(c.x); + uchar *outBits = texInfo->image.scanLine(int(c.y) - padding) + int(c.x) - padding; for (int y = 0; y < glyph.height(); ++y) { memcpy(outBits, inBits, glyph.width()); inBits += glyph.width(); @@ -175,13 +187,13 @@ void QSGDefaultDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> if (useTextureUploadWorkaround()) { for (int i = 0; i < glyph.height(); ++i) { m_funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, - c.x, c.y + i, glyph.width(),1, + c.x - padding, c.y + i - padding, glyph.width(),1, format, GL_UNSIGNED_BYTE, glyph.scanLine(i)); } } else { m_funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, - c.x, c.y, glyph.width(), glyph.height(), + c.x - padding, c.y - padding, glyph.width(), glyph.height(), format, GL_UNSIGNED_BYTE, glyph.constBits()); } diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h index f7314776d6..2f9331f6d8 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h @@ -73,8 +73,9 @@ private: QSize size; QRect allocatedArea; QDistanceField image; + int padding; - TextureInfo() : texture(0) + TextureInfo() : texture(0), padding(-1) { } }; diff --git a/src/quick/scenegraph/qsgdefaultimagenode.cpp b/src/quick/scenegraph/qsgdefaultimagenode.cpp index 69df506d2a..7f85c31ccb 100644 --- a/src/quick/scenegraph/qsgdefaultimagenode.cpp +++ b/src/quick/scenegraph/qsgdefaultimagenode.cpp @@ -140,11 +140,10 @@ void SmoothTextureMaterialShader::initialize() QSGDefaultImageNode::QSGDefaultImageNode() : m_innerSourceRect(0, 0, 1, 1) , m_subSourceRect(0, 0, 1, 1) + , m_antialiasing(false) , m_mirror(false) , m_dirtyGeometry(false) , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) - , m_antialiasing(AntialiasingNone) - { setMaterial(&m_materialO); setOpaqueMaterial(&m_material); @@ -250,20 +249,10 @@ void QSGDefaultImageNode::setTexture(QSGTexture *texture) void QSGDefaultImageNode::setAntialiasing(bool antialiasing) { - AntialiasingFlags antialiasingFlags = antialiasing - ? AntialiasingAll - : AntialiasingNone; - - setAntialiasing(antialiasingFlags); -} - -void QSGDefaultImageNode::setAntialiasing(AntialiasingFlags antialiasingFlags) -{ - if (antialiasingFlags == m_antialiasing) + if (antialiasing == m_antialiasing) return; - - m_antialiasing = antialiasingFlags; - if (m_antialiasing != AntialiasingNone) { + m_antialiasing = antialiasing; + if (m_antialiasing) { setMaterial(&m_smoothMaterial); setOpaqueMaterial(0); setGeometry(new QSGGeometry(smoothAttributeSet(), 0)); @@ -375,14 +364,11 @@ void QSGDefaultImageNode::updateGeometry() } // An image can be rendered as a single quad if: - // - There is antialiasing on all or no edges // - There are no margins, and either: // - the image isn't repeated // - the source rectangle fills the entire texture so that texture wrapping can be used, // and NPOT is supported - if (!hasMargins - && (m_antialiasing == AntialiasingAll || m_antialiasing == AntialiasingNone) - && (!hasTiles || (fullTexture && wrapSupported))) { + if (!hasMargins && (!hasTiles || (fullTexture && wrapSupported))) { QRectF sr; if (!fullTexture) { sr = QRectF(innerSourceRect.x() + (m_subSourceRect.left() - floorLeft) * innerSourceRect.width(), @@ -561,35 +547,10 @@ void QSGDefaultImageNode::updateGeometry() topDv = bottomDv *= 0.5f; } - if (!m_antialiasing.testFlag(AntialiasingTop)) { - topDy = 0.0f; - topDv = 0.0f; - } - - if (!m_antialiasing.testFlag(AntialiasingBottom)) { - bottomDy = 0.0f; - bottomDv = 0.0f; - } - - if (!m_antialiasing.testFlag(AntialiasingLeft)) { - leftDx = 0.0f; - leftDu = 0.0f; - } - - if (!m_antialiasing.testFlag(AntialiasingRight)) { - rightDx = 0.0f; - rightDu = 0.0f; - } - // This delta is how much the fuzziness can reach out from the image. float delta = float(qAbs(m_targetRect.width()) < qAbs(m_targetRect.height()) ? m_targetRect.width() : m_targetRect.height()) * 0.5f; - float deltaTop = m_antialiasing.testFlag(AntialiasingTop) ? delta : 0.0f; - float deltaBottom = m_antialiasing.testFlag(AntialiasingBottom) ? delta : 0.0f; - float deltaLeft = m_antialiasing.testFlag(AntialiasingLeft) ? delta : 0.0f; - float deltaRight = m_antialiasing.testFlag(AntialiasingRight) ? delta : 0.0f; - quint16 index = 0; ys = yData.data(); for (int j = 0; j < vCells; ++j, ys += 2) { @@ -639,28 +600,28 @@ void QSGDefaultImageNode::updateGeometry() if (isTop) { vertices[topLeft].dy = vertices[topRight].dy = topDy; vertices[topLeft].dv = vertices[topRight].dv = topDv; - vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -deltaTop; + vertices[topLeft + 1].dy = vertices[topRight + 1].dy = -delta; appendQuad(&indices, topLeft + 1, topRight + 1, topLeft, topRight); } if (isBottom) { vertices[bottomLeft].dy = vertices[bottomRight].dy = -bottomDy; vertices[bottomLeft].dv = vertices[bottomRight].dv = -bottomDv; - vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = deltaBottom; + vertices[bottomLeft + 1].dy = vertices[bottomRight + 1].dy = delta; appendQuad(&indices, bottomLeft, bottomRight, bottomLeft + 1, bottomRight + 1); } if (isLeft) { vertices[topLeft].dx = vertices[bottomLeft].dx = leftDx; vertices[topLeft].du = vertices[bottomLeft].du = leftDu; - vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -deltaLeft; + vertices[topLeft + 1].dx = vertices[bottomLeft + 1].dx = -delta; appendQuad(&indices, topLeft + 1, topLeft, bottomLeft + 1, bottomLeft); } if (isRight) { vertices[topRight].dx = vertices[bottomRight].dx = -rightDx; vertices[topRight].du = vertices[bottomRight].du = -rightDu; - vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = deltaRight; + vertices[topRight + 1].dx = vertices[bottomRight + 1].dx = delta; appendQuad(&indices, topRight, topRight + 1, bottomRight, bottomRight + 1); } } diff --git a/src/quick/scenegraph/qsgdefaultimagenode_p.h b/src/quick/scenegraph/qsgdefaultimagenode_p.h index 558e4d8ba4..26b087284b 100644 --- a/src/quick/scenegraph/qsgdefaultimagenode_p.h +++ b/src/quick/scenegraph/qsgdefaultimagenode_p.h @@ -62,7 +62,6 @@ public: virtual void setSubSourceRect(const QRectF &rect); virtual void setTexture(QSGTexture *t); virtual void setAntialiasing(bool antialiasing); - virtual void setAntialiasing(AntialiasingFlags antialiasing); virtual void setMirror(bool mirror); virtual void update(); @@ -85,11 +84,11 @@ private: QSGTextureMaterial m_materialO; QSGSmoothTextureMaterial m_smoothMaterial; + uint m_antialiasing : 1; uint m_mirror : 1; uint m_dirtyGeometry : 1; QSGGeometry m_geometry; - AntialiasingFlags m_antialiasing; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp index 6f54b258ff..f635ccd17b 100644 --- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp +++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp @@ -399,176 +399,6 @@ void QSGSharedDistanceFieldGlyphCache::unregisterOwnerElement(QQuickItem *ownerE } } -#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG_) -# include <QtOpenGL/private/qglextensions_p.h> - -void QSGSharedDistanceFieldGlyphCache::saveTexture(GLuint textureId, int width, int height) -{ - GLuint fboId; - glGenFramebuffers(1, &fboId); - - GLuint tmpTexture = 0; - glGenTextures(1, &tmpTexture); - glBindTexture(GL_TEXTURE_2D, tmpTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); - - glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId); - glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, - tmpTexture, 0); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, textureId); - - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - - GLfloat textureCoordinateArray[8]; - textureCoordinateArray[0] = 0.0f; - textureCoordinateArray[1] = 0.0f; - textureCoordinateArray[2] = 1.0f; - textureCoordinateArray[3] = 0.0f; - textureCoordinateArray[4] = 1.0f; - textureCoordinateArray[5] = 1.0f; - textureCoordinateArray[6] = 0.0f; - textureCoordinateArray[7] = 1.0f; - - GLfloat vertexCoordinateArray[8]; - vertexCoordinateArray[0] = -1.0f; - vertexCoordinateArray[1] = -1.0f; - vertexCoordinateArray[2] = 1.0f; - vertexCoordinateArray[3] = -1.0f; - vertexCoordinateArray[4] = 1.0f; - vertexCoordinateArray[5] = 1.0f; - vertexCoordinateArray[6] = -1.0f; - vertexCoordinateArray[7] = 1.0f; - - glViewport(0, 0, width, height); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray); - - { - static const char vertexShaderSource[] = - "attribute highp vec4 vertexCoordsArray; \n" - "attribute highp vec2 textureCoordArray; \n" - "varying highp vec2 textureCoords; \n" - "void main(void) \n" - "{ \n" - " gl_Position = vertexCoordsArray; \n" - " textureCoords = textureCoordArray; \n" - "} \n"; - - static const char fragmentShaderSource[] = - "varying highp vec2 textureCoords; \n" - "uniform sampler2D texture; \n" - "void main() \n" - "{ \n" - " gl_FragColor = texture2D(texture, textureCoords); \n" - "} \n"; - - GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); - GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - - if (vertexShader == 0 || fragmentShader == 0) { - GLenum error = glGetError(); - qWarning("SharedGraphicsCacheServer::setupShaderPrograms: Failed to create shaders. (GL error: %x)", - error); - return; - } - - glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); - glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); - glCompileShader(vertexShader); - - GLint len = 1; - glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &len); - - char infoLog[2048]; - glGetShaderInfoLog(vertexShader, 2048, NULL, infoLog); - if (qstrlen(infoLog) > 0) { - qWarning("SharedGraphicsCacheServer::setupShaderPrograms, problems compiling vertex shader:\n %s", - infoLog); - //return; - } - - glCompileShader(fragmentShader); - glGetShaderInfoLog(fragmentShader, 2048, NULL, infoLog); - if (qstrlen(infoLog) > 0) { - qWarning("SharedGraphicsCacheServer::setupShaderPrograms, problems compiling fragent shader:\n %s", - infoLog); - //return; - } - - GLuint shaderProgram = glCreateProgram(); - glAttachShader(shaderProgram, vertexShader); - glAttachShader(shaderProgram, fragmentShader); - - glBindAttribLocation(shaderProgram, 0, "vertexCoordsArray"); - glBindAttribLocation(shaderProgram, 1, "textureCoordArray"); - - glLinkProgram(shaderProgram); - glGetProgramInfoLog(shaderProgram, 2048, NULL, infoLog); - if (qstrlen(infoLog) > 0) { - qWarning("SharedGraphicsCacheServer::setupShaderPrograms, problems linking shaders:\n %s", - infoLog); - //return; - } - - glUseProgram(shaderProgram); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - - int textureUniformLocation = glGetUniformLocation(shaderProgram, "_qt_texture"); - glUniform1i(textureUniformLocation, 0); - } - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - { - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - qWarning("SharedGraphicsCacheServer::readBackBuffer: glDrawArrays reported error 0x%x", - error); - } - } - - uchar *data = new uchar[width * height * 4]; - - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); - - QImage image(width, height, QImage::Format_ARGB32); - quint32 *dest = reinterpret_cast<quint32 *>(image.bits()); - for (int i=0; i<width*height; ++i) - dest[i] = qRgba(0xff, 0xff, 0xff, data[i]); - - QByteArray fileName = m_cacheId + ' ' + QByteArray::number(textureId); - fileName = fileName.replace('/', '_').replace(' ', '_') + ".png"; - image.save(QString::fromLocal8Bit(fileName)); - - { - GLenum error = glGetError(); - if (error != GL_NO_ERROR) { - qWarning("SharedGraphicsCacheServer::readBackBuffer: glReadPixels reported error 0x%x", - error); - } - } - - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - - glDeleteFramebuffers(1, &fboId); - glDeleteTextures(1, &tmpTexture); - - delete[] data; -} -#endif - namespace { struct TextureContent { QSize size; @@ -683,9 +513,6 @@ void QSGSharedDistanceFieldGlyphCache::processPendingGlyphs() texture.textureId = m_sharedGraphicsCache->textureIdForBuffer(it.key()); texture.size = m_sharedGraphicsCache->sizeOfBuffer(it.key()); -#if defined(QSGSHAREDDISTANCEFIELDGLYPHCACHE_DEBUG_) - saveTexture(texture.textureId, texture.size.width(), texture.size.height()); -#endif setGlyphsTexture(it.value().glyphs, texture); ++it; diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 469cd1d21b..58d618a049 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -38,6 +38,7 @@ #include <QtGui/QScreen> #include <QtGui/QGuiApplication> +#include <QtGui/QOffscreenSurface> #include <QtQuick/private/qsgcontext_p.h> #include <QtQuick/private/qquickwindow_p.h> @@ -214,15 +215,29 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window) hide(window); QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); - if (m_gl) - m_gl->makeCurrent(window); + bool current = false; + QScopedPointer<QOffscreenSurface> offscreenSurface; + if (m_gl) { + QSurface *surface = window; + // There may be no platform window if the window got closed. + if (!window->handle()) { + offscreenSurface.reset(new QOffscreenSurface); + offscreenSurface->setFormat(m_gl->format()); + offscreenSurface->create(); + surface = offscreenSurface.data(); + } + current = m_gl->makeCurrent(surface); + } + if (Q_UNLIKELY(!current)) + qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context"; + d->cleanupNodesOnShutdown(); if (m_windows.size() == 0) { d->context->invalidate(); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); delete m_gl; m_gl = 0; - } else if (m_gl) { + } else if (m_gl && current) { m_gl->doneCurrent(); } } diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index bcb523f90d..480ac5e569 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -1,6 +1,7 @@ !contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL # DEFINES += QSG_SEPARATE_INDEX_BUFFER +# DEFINES += QSG_DISTANCEFIELD_CACHE_DEBUG # Core API HEADERS += \ diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp index 27b9e656ec..34e00e0b01 100644 --- a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp +++ b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp @@ -299,6 +299,8 @@ QSGSimpleTextureNode::TextureCoordinatesTransformMode QSGSimpleTextureNode::text By default, the node does not take ownership of the texture. \sa setTexture() + + \since 5.4 */ void QSGSimpleTextureNode::setOwnsTexture(bool owns) { @@ -308,6 +310,8 @@ void QSGSimpleTextureNode::setOwnsTexture(bool owns) /*! Returns \c true if the node takes ownership of the texture; otherwise returns \c false. + + \since 5.4 */ bool QSGSimpleTextureNode::ownsTexture() const { |