diff options
Diffstat (limited to 'src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp')
-rw-r--r-- | src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp | 324 |
1 files changed, 0 insertions, 324 deletions
diff --git a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp deleted file mode 100644 index 3dfa1bd269..0000000000 --- a/src/declarative/scenegraph/qsgdefaultdistancefieldglyphcache.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsgdefaultdistancefieldglyphcache_p.h" - -#include <private/qsgdistancefieldutil_p.h> -#include <qopenglfunctions.h> - -QT_BEGIN_NAMESPACE - -QHash<QString, QOpenGLMultiGroupSharedResource> QSGDefaultDistanceFieldGlyphCache::m_textures_data; - -QSGDefaultDistanceFieldGlyphCache::DistanceFieldTextureData *QSGDefaultDistanceFieldGlyphCache::textureData(QOpenGLContext *c) -{ - QString key = QString::fromLatin1("%1_%2_%3_%4") - .arg(font().familyName()) - .arg(font().styleName()) - .arg(font().weight()) - .arg(font().style()); - return m_textures_data[key].value<QSGDefaultDistanceFieldGlyphCache::DistanceFieldTextureData>(c); -} - -QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font) - : QSGDistanceFieldGlyphCache(man, c, font) - , m_maxTextureSize(0) -{ - m_textureData = textureData(c); -} - -void QSGDefaultDistanceFieldGlyphCache::requestGlyphs(const QVector<glyph_t> &glyphs) -{ - int count = glyphs.count(); - - // Avoid useless and costly glyph re-generation - if (cacheIsFull() && !m_textureData->unusedGlyphs.isEmpty()) { - for (int i = 0; i < count; ++i) { - glyph_t glyphIndex = glyphs.at(i); - if (containsGlyph(glyphIndex) && m_textureData->unusedGlyphs.contains(glyphIndex)) - m_textureData->unusedGlyphs.remove(glyphIndex); - } - } - - QList<GlyphPosition> glyphPositions; - QVector<glyph_t> glyphsToRender; - - for (int i = 0; i < count; ++i) { - glyph_t glyphIndex = glyphs.at(i); - - if (++m_textureData->glyphRefCount[glyphIndex] == 1) - m_textureData->unusedGlyphs.remove(glyphIndex); - - if (cacheIsFull() && m_textureData->unusedGlyphs.isEmpty()) - continue; - - GlyphPosition p; - p.glyph = glyphIndex; - p.position = QPointF(m_textureData->currX, m_textureData->currY); - - if (!cacheIsFull()) { - m_textureData->currX += QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()); - if (m_textureData->currX >= maxTextureSize()) { - m_textureData->currX = 0; - m_textureData->currY += QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()); - } - } else { - // Recycle glyphs - if (!m_textureData->unusedGlyphs.isEmpty()) { - glyph_t unusedGlyph = *m_textureData->unusedGlyphs.constBegin(); - TexCoord unusedCoord = glyphTexCoord(unusedGlyph); - p.position = QPointF(unusedCoord.x, unusedCoord.y); - m_textureData->unusedGlyphs.remove(unusedGlyph); - removeGlyph(unusedGlyph); - } - } - - if (p.position.y() < maxTextureSize()) { - glyphPositions.append(p); - glyphsToRender.append(glyphIndex); - } - } - - addGlyphPositions(glyphPositions); - markGlyphsToRender(glyphsToRender); -} - -void QSGDefaultDistanceFieldGlyphCache::storeGlyphs(const QHash<glyph_t, QImage> &glyphs) -{ - int requiredWidth = maxTextureSize(); - int rows = 128 / (requiredWidth / QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution())); // Enough rows to fill the latin1 set by default.. - int requiredHeight = qMin(maxTextureSize(), - qMax(m_textureData->currY + QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()), - QT_DISTANCEFIELD_TILESIZE(doubleGlyphResolution()) * rows)); - - resizeTexture((requiredWidth), (requiredHeight)); - glBindTexture(GL_TEXTURE_2D, m_textureData->texture); - - QVector<glyph_t> glyphTextures; - - QHash<glyph_t, QImage>::const_iterator it; - for (it = glyphs.constBegin(); it != glyphs.constEnd(); ++it) { - glyph_t glyphIndex = it.key(); - TexCoord c = glyphTexCoord(glyphIndex); - - glyphTextures.append(glyphIndex); - - QImage glyph = it.value(); - - if (useWorkaroundBrokenFBOReadback()) { - uchar *inBits = glyph.scanLine(0); - uchar *outBits = m_textureData->image.scanLine(int(c.y)) + int(c.x); - for (int y = 0; y < glyph.height(); ++y) { - qMemCopy(outBits, inBits, glyph.width()); - inBits += glyph.bytesPerLine(); - outBits += m_textureData->image.bytesPerLine(); - } - } - - glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, glyph.width(), glyph.height(), GL_ALPHA, GL_UNSIGNED_BYTE, glyph.constBits()); - } - - Texture t; - t.textureId = m_textureData->texture; - t.size = m_textureData->size; - addGlyphTextures(glyphTextures, t); -} - -void QSGDefaultDistanceFieldGlyphCache::releaseGlyphs(const QVector<glyph_t> &glyphs) -{ - int count = glyphs.count(); - for (int i = 0; i < count; ++i) { - glyph_t glyphIndex = glyphs.at(i); - if (--m_textureData->glyphRefCount[glyphIndex] == 0 && !glyphTexCoord(glyphIndex).isNull()) - m_textureData->unusedGlyphs.insert(glyphIndex); - } -} - -void QSGDefaultDistanceFieldGlyphCache::createTexture(int width, int height) -{ - if (useWorkaroundBrokenFBOReadback() && m_textureData->image.isNull()) - m_textureData->image = QImage(width, height, QImage::Format_Indexed8); - - while (glGetError() != GL_NO_ERROR) { } - - glGenTextures(1, &m_textureData->texture); - glBindTexture(GL_TEXTURE_2D, m_textureData->texture); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - m_textureData->size = QSize(width, height); - - GLuint error = glGetError(); - if (error != GL_NO_ERROR) { - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &m_textureData->texture); - m_textureData->texture = 0; - } - -} - -void QSGDefaultDistanceFieldGlyphCache::resizeTexture(int width, int height) -{ - int oldWidth = m_textureData->size.width(); - int oldHeight = m_textureData->size.height(); - if (width == oldWidth && height == oldHeight) - return; - - GLuint oldTexture = m_textureData->texture; - createTexture(width, height); - - if (!oldTexture) - return; - - updateTexture(oldTexture, m_textureData->texture, m_textureData->size); - - if (useWorkaroundBrokenFBOReadback()) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, m_textureData->image.constBits()); - m_textureData->image = m_textureData->image.copy(0, 0, width, height); - glDeleteTextures(1, &oldTexture); - return; - } - - if (!m_textureData->blitProgram) - m_textureData->createBlitProgram(); - - Q_ASSERT(m_textureData->blitProgram); - - if (!m_textureData->fbo) - ctx->functions()->glGenFramebuffers(1, &m_textureData->fbo); - ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_textureData->fbo); - - GLuint tmp_texture; - glGenTextures(1, &tmp_texture); - glBindTexture(GL_TEXTURE_2D, tmp_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); - ctx->functions()->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, tmp_texture, 0); - - ctx->functions()->glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, oldTexture); - - // save current render states - GLboolean stencilTestEnabled; - GLboolean depthTestEnabled; - GLboolean scissorTestEnabled; - GLboolean blendEnabled; - GLint viewport[4]; - GLint oldProgram; - glGetBooleanv(GL_STENCIL_TEST, &stencilTestEnabled); - glGetBooleanv(GL_DEPTH_TEST, &depthTestEnabled); - glGetBooleanv(GL_SCISSOR_TEST, &scissorTestEnabled); - glGetBooleanv(GL_BLEND, &blendEnabled); - glGetIntegerv(GL_VIEWPORT, &viewport[0]); - glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgram); - - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - - glViewport(0, 0, oldWidth, oldHeight); - - ctx->functions()->glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureData->blitVertexCoordinateArray); - ctx->functions()->glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureData->blitTextureCoordinateArray); - - m_textureData->blitProgram->bind(); - m_textureData->blitProgram->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR)); - m_textureData->blitProgram->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR)); - m_textureData->blitProgram->disableAttributeArray(int(QT_OPACITY_ATTR)); - m_textureData->blitProgram->setUniformValue("imageTexture", GLuint(0)); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glBindTexture(GL_TEXTURE_2D, m_textureData->texture); - - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); - - ctx->functions()->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, 0); - glDeleteTextures(1, &tmp_texture); - glDeleteTextures(1, &oldTexture); - - ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, 0); - - // restore render states - if (stencilTestEnabled) - glEnable(GL_STENCIL_TEST); - if (depthTestEnabled) - glEnable(GL_DEPTH_TEST); - if (scissorTestEnabled) - glEnable(GL_SCISSOR_TEST); - if (blendEnabled) - glEnable(GL_BLEND); - glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); - ctx->functions()->glUseProgram(oldProgram); -} - -bool QSGDefaultDistanceFieldGlyphCache::useWorkaroundBrokenFBOReadback() const -{ - static bool set = false; - static bool useWorkaround = false; - if (!set) { - QOpenGLContextPrivate *ctx_p = static_cast<QOpenGLContextPrivate *>(QOpenGLContextPrivate::get(ctx)); - useWorkaround = ctx_p->workaround_brokenFBOReadBack; - set = true; - } - return useWorkaround; -} - -int QSGDefaultDistanceFieldGlyphCache::maxTextureSize() const -{ - if (!m_maxTextureSize) - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); - return m_maxTextureSize; -} - -QT_END_NAMESPACE |