diff options
author | Jason Barron <jbarron@trolltech.com> | 2010-07-05 14:38:57 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2010-07-12 07:03:17 (GMT) |
commit | 0113025720a1a07ac6a40b1f9c95746a904fdf4e (patch) | |
tree | 217b6bac7aed2f5854743c2870b47e5d2eb73f72 /src/openvg | |
parent | edd3ffa92df8c6e0fb68f3eb6e10872e69532c90 (diff) | |
download | Qt-0113025720a1a07ac6a40b1f9c95746a904fdf4e.zip Qt-0113025720a1a07ac6a40b1f9c95746a904fdf4e.tar.gz Qt-0113025720a1a07ac6a40b1f9c95746a904fdf4e.tar.bz2 |
Minor modifications and optimizations to the Symbian HW glyph cache.
After the latest round of API reviews, the Symbian glyph cache has now
been moved from GDI to FBS and this required some changes in Qt's
implementation.
Also incorporate an optimization where we first iterate over the glyph
vector to eliminate glyphs that are already cached in Qt's glyph cache.
This way we only open the glyph iterator on glyphs that we need.
Reviewed-by: Alessandro Portale
Diffstat (limited to 'src/openvg')
-rw-r--r-- | src/openvg/qvg_symbian.cpp | 109 |
1 files changed, 60 insertions, 49 deletions
diff --git a/src/openvg/qvg_symbian.cpp b/src/openvg/qvg_symbian.cpp index 9bcb6f5..0e6e773 100644 --- a/src/openvg/qvg_symbian.cpp +++ b/src/openvg/qvg_symbian.cpp @@ -41,15 +41,16 @@ #include "qpixmapdata_vg_p.h" #include "qvgfontglyphcache_p.h" +#include <private/qt_s60_p.h> + +#include <fbs.h> +#include <bitdev.h> #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE -# include <private/qt_s60_p.h> -# include <fbs.h> -# include <gdi.h> # include <sgresource/sgimage.h> -# ifdef SYMBIAN_GDI_GLYPHDATA // defined in gdi.h +# ifdef SYMBIAN_FBSERV_GLYPHDATA // defined in fbs.h # define QT_SYMBIAN_HARDWARE_GLYPH_CACHE -# include <graphics/glyphdataiterator.h> +# include <graphics/fbsglyphdataiterator.h> # include <private/qfontengine_s60_p.h> # endif #endif @@ -101,6 +102,7 @@ static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap) return copy; } +#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE static VGImage sgImageToVGImage(QEglContext *context, const RSgImage &sgImage) { // when "0" used as argument then @@ -155,6 +157,7 @@ static VGImage sgImageToVGImage(QEglContext *context, const RSgImage &sgImage) driver.Close(); return vgImage; } +#endif void QVGPixmapData::cleanup() { @@ -329,56 +332,64 @@ void QSymbianVGFontGlyphCache::cacheGlyphs(QVGPaintEnginePrivate *d, const glyph_t *g, int count) { #ifdef QT_SYMBIAN_HARDWARE_GLYPH_CACHE - QFontEngineS60 *fontEngine = static_cast<QFontEngineS60*>(ti.fontEngine); - CFont *cfont = fontEngine->m_activeFont; - -// QVarLengthArray<glyph_t, 256> adjustedGlyphs(glyphs); -// for (int i = 0; i < glyphs.count(); ++i) -// adjustedGlyphs[i] |= 0x80000000; - - RGlyphDataIterator iter; - int err = iter.Open(*cfont, (const unsigned int*)glyphs.constData(), glyphs.count()); - - if (err == KErrNotSupported || err == KErrInUse) { // Fallback in possibly supported error cases - iter.Close(); - qWarning("Falling back to default QVGFontGlyphCache"); - return QVGFontGlyphCache::cacheGlyphs(d, ti, glyphs); - } + QFontEngineS60 *s60fontEngine = static_cast<QFontEngineS60*>(fontEngine); + if (s60fontEngine->m_activeFont->TypeUid() != KCFbsFontUid) + return QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count); - for (; err == KErrNone; err = iter.Next()) { + QVector<glyph_t> uncachedGlyphs; + while (count-- > 0) { // Skip this glyph if we have already cached it before. - const unsigned int glyph = iter.GlyphCode(); + glyph_t glyph = *g++; if (((glyph < 256) && ((cachedGlyphsMask[glyph / 32] & (1 << (glyph % 32))) != 0)) || cachedGlyphs.contains(glyph)) - continue; - - const RSgImage& image = iter.Image(); - const TOpenFontCharMetrics& metrics = iter.Metrics(); - - TRect glyphBounds; - metrics.GetHorizBounds(glyphBounds); - VGImage vgImage = sgImageToVGImage(0, image); - VGfloat origin[2]; - VGfloat escapement[2]; - origin[0] = -glyphBounds.iTl.iX + 0.5f; - origin[1] = glyphBounds.iBr.iY + 0.5f; - escapement[0] = metrics.HorizAdvance(); - escapement[1] = 0; - vgSetGlyphToImage(font, iter.GlyphCode(), vgImage, origin, escapement); - vgDestroyImage(vgImage); - - // Add to cache - if (glyph < 256) - cachedGlyphsMask[glyph / 32] |= (1 << (glyph % 32)); - else - cachedGlyphs.insert(glyph); + continue; + if (!uncachedGlyphs.contains(glyph)) + uncachedGlyphs.append(glyph); } - iter.Close(); - if (err == KErrNoMemory || err == KErrNoGraphicsMemory) - qWarning("Not enough memory to cache glyph"); - else if (err != KErrNotFound) - qWarning("Received error %d from glyph cache", err); + if (!uncachedGlyphs.isEmpty()) { + CFbsFont *cfbsFont = static_cast<CFbsFont *>(s60fontEngine->m_activeFont); + RFbsGlyphDataIterator iter; + + int err = iter.Open(*cfbsFont, (const unsigned int*)uncachedGlyphs.constData(), uncachedGlyphs.count()); + + if (err == KErrNotSupported || err == KErrInUse) { // Fallback in possibly supported error cases + iter.Close(); + qWarning("Falling back to default QVGFontGlyphCache"); + return QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count); + } + + for (; err == KErrNone; err = iter.Next()) { + const unsigned int glyph = iter.GlyphCode(); + + const RSgImage& image = iter.Image(); + const TOpenFontCharMetrics& metrics = iter.Metrics(); + + TRect glyphBounds; + metrics.GetHorizBounds(glyphBounds); + VGImage vgImage = sgImageToVGImage(0, image); + VGfloat origin[2]; + VGfloat escapement[2]; + origin[0] = -glyphBounds.iTl.iX; + origin[1] = glyphBounds.iBr.iY; + escapement[0] = 0; + escapement[1] = 0; + vgSetGlyphToImage(font, glyph, vgImage, origin, escapement); + vgDestroyImage(vgImage); + + // Add to cache + if (glyph < 256) + cachedGlyphsMask[glyph / 32] |= (1 << (glyph % 32)); + else + cachedGlyphs.insert(glyph); + } + iter.Close(); + + if (err == KErrNoMemory || err == KErrNoGraphicsMemory) + qWarning("Not enough memory to cache glyph"); + else if (err != KErrNotFound) + qWarning("Received error %d from glyph cache", err); + } #else QVGFontGlyphCache::cacheGlyphs(d, fontEngine, g, count); #endif |